#include <sys/syslog.h>
#include <time.h>
#include <unistd.h>
#include <stdatomic.h>
#include <float.h>

#include "collector-api.h"
#include "deviceLayer.h" 
#include "emsctrlProc.h"
#include "discover.h"
#include "./jsonct.h"
#include "lnxall_buffer.h"

#include "log_upper_data.h"
#include "../business_log/business_log.h"
#include "microgridtopology.h"
//  注意：光伏交流耦合，易出现多并柜场景，因此业务软件设计是基于主从模式设计的，微网业务层在proto_forward中，DOD保护、等其他逻辑在emu_lc中实现；
//  即，微网交流耦合必须使能主从模式
//  即，此处设置并离网、开关机、功率操作对象是LC设备，设置光伏开关机、功率操作对象是PV设备
#define UP_PV_KM 0.2
#define DOWN_PV_KM 1
#define SOC_KM 0.2

struct UD_log *ac_micro_log;

// 在标准逻辑中，强切标志不用，此功能用于项目定制开发使用

static char *micro_state_tab[] =
{
	"待机状态",
	"市电并网状态",
	"离网状态",
	"柴发并网状态",
	"初始状态",
	"异常状态",
    "默认状态"
};

// 动作执行超时，异常描述映射map
static micro_abnormal_msg_t micro_abnormal_tab[] =
{
	{LCB_SIGN_ON, "trigger abnormal: 负载断路器合闸异常"},
	{LCB_SIGN_OFF, "trigger abnormal: 负载断路器分闸异常"},
	{ICB_SIGN_ON,  "trigger abnormal: 并离网断路器合闸异常"},
	{ICB_SIGN_OFF, "trigger abnormal: 并离网断路器分闸异常"},
	{DG_SIGN_ON,   "trigger abnormal: 柴发启动异常"},
	{DG_SIGN_OFF,  "trigger abnormal: 柴发关机异常"},
};


static void print_abnormal_result(ABNORMAL code){
    char *abnormal_msg = NULL;
    int i;
    for (i = 0; i < sizeof(micro_abnormal_tab) / sizeof(micro_abnormal_tab[0]); i++)
    {
        if (micro_abnormal_tab[i].code == code)
        {
            abnormal_msg = micro_abnormal_tab[i].msg;
            break;
        }
    }
    if (i >= 0) 
       i =10;
    micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "~~: %s ", abnormal_msg);
}

static time_t startTime = -1;
 /**
  * @description: 检查动作执行是否超时，超时则进入异常状态，异常状态想往其他状态切，需人工排查异常确认没问题后，手动清除对应异常标志点位
  * @param  p 异常缓存变量， tag EMS异常点位， value 动作（1合闸/2分闸  1启机/2停机），code 异常描述码
  * @return 无
  * @attention 当前只对，负载断路器分合闸、并离网断路器合闸、柴发启停进行动作超时检查~~
  */
static void check_action_timeout(int *p, char *tag, int value, ABNORMAL code){
    time_t currentTime = -1;
    time(&currentTime);
    int action_timeout = microgrid_ctrl.action_timeout == 0 ? 120 : microgrid_ctrl.action_timeout;

    double elapsedTime = difftime(currentTime, startTime);
    if (elapsedTime >= action_timeout) {
        dev_set_dev_tag_int(DEV_NO_EMS, tag, value);
        *p = value;
        print_abnormal_result(code);
    }
}

// bit_set(microgrid_ctrl.cut_flag, BIT_STATE_OFF_GRID, 1);  

static battery_flag_t battery_flag[CABINET_NUM_MAX] = {0};

static current_stat_t ac_state_machine;
static current_stat_t *get_ac_state_machine(void)
{
    return &ac_state_machine;
}

static bool offgrid_condition_with_sts(dev_info_all_t *var, int value, unsigned int pos){
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){ 
        if (microgrid_cfg.en_ats){
            if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
                if (microgrid_data.offgrid_statu == 1)
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_mains){
        if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
            if (microgrid_data.offgrid_statu == 1)
                return true;
        }
    }
    else if (microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
            if (microgrid_data.offgrid_statu == 1)
                return true;
        }   
    }
    else //>>柴发和市电都未使能，纯离网
        return true;
    return false;
}

static bool offgrid_condition_with_cirbreak(dev_info_all_t *var, int value, unsigned int pos){
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_ats){// 柴发和市电都使能，必须开启ATS，电操断路器和STS可选任意一个
            if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
                if (_dido->info.dido_data.conn_sign == 0 && _dido->info.dido_data.icb_sign == 0)
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_mains){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
            if (_dido->info.dido_data.conn_sign == 0 && _dido->info.dido_data.icb_sign == 0)
                return true;
        }
    }
    else if (microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
            if (_dido->info.dido_data.conn_sign == 0 && _dido->info.dido_data.icb_sign == 0)
                return true;
        }    
    }
    else //>>柴发和市电都未使能，纯离网
        return true;
    return false;
}

static bool offgrid_condition_with_none(dev_info_all_t *var, int value, unsigned int pos){ // ***
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        return false;
    }
    else if (microgrid_cfg.en_mains){
        return false;
    }
    else if (microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 0){
            if ((bit_get(microgrid_ctrl.cut_flag, BIT_STATE_CF_CONNECT_GRID) == 0) && _dido->info.dido_data.conn_sign == 0){ // 防止柴发并网init过程中，柴发开机较慢，导致意外进入离网
                return true;
            }
        }    
    }
    else //>>柴发和市电都未使能，纯离网
        return true;
    return false;
}

static bool offgrid_condition_with_force(dev_info_all_t *var, int value, unsigned int pos){
    if (bit_get(microgrid_ctrl.cut_flag, pos)){
        return true;
    }
    return false;
}
/***********************************/
static bool cfgrid_condition_with_sts(dev_info_all_t *var, int value, unsigned int pos){
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_ats){
            if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
                if (microgrid_data.grid_statu == 1 && _dido->info.dido_data.ats_sign == 0)
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
            if (microgrid_data.grid_statu == 1)
                return true;
        }
    }
    return false;
}

static bool cfgrid_condition_with_cirbreak(dev_info_all_t *var, int value, unsigned int pos){
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_ats){// 柴发和市电都使能，必须开启ATS，电操断路器和STS可选任意一个
            if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
                if (_dido->info.dido_data.conn_sign == 1 && _dido->info.dido_data.ats_sign == 0) // 1. 主->备电源切换、断路器自动分闸 2. 离网->备电源、断路器保持分闸状态
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
            if (_dido->info.dido_data.conn_sign == 1)
                return true;
        }  
    }
    return false;
}

static bool cfgrid_condition_with_none(dev_info_all_t *var, int value, unsigned int pos){ // ***
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains == 0 && microgrid_cfg.en_diesel_generator == 1){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 0){
            if ((bit_get(microgrid_ctrl.cut_flag, BIT_STATE_OFF_GRID) == 0) && _dido->info.dido_data.conn_sign == 1){ // 防止离网init过程中，柴发关机较慢，导致意外进入柴发并网
                return true;
            }
        }
    }
    return false;
}

static bool cfgrid_condition_with_force(dev_info_all_t *var, int value, unsigned int pos){ // 状态机支持强切功能
    if (bit_get(microgrid_ctrl.cut_flag, pos)){
        return true;
    }
    return false;
}
/*****************************************/
static bool grid_condition_with_sts(dev_info_all_t *var, int value, unsigned int pos){
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_ats){
            if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
                if (microgrid_data.grid_statu == 1 && _dido->info.dido_data.ats_sign == 1)
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_mains){
        if (microgrid_cfg.en_sts == 1 && microgrid_cfg.en_icb == 0){
            if (microgrid_data.grid_statu == 1)
                return true;
        }
    }
    return false;
}

static bool grid_condition_with_cirbreak(dev_info_all_t *var, int value, unsigned int pos){
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains && microgrid_cfg.en_diesel_generator){
        if (microgrid_cfg.en_ats){// 柴发和市电都使能，必须开启ATS，电操断路器和STS可选任意一个
            if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
                if (_dido->info.dido_data.conn_sign == 1 && _dido->info.dido_data.ats_sign == 1) // 1. 备->主电源切换、断路器自动分闸 2. 离网->主电源、断路器保持分闸状态
                    return true;
            }
        }else{
            micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY,  "ATS must be opened!!!");
            return false;
        }
    }
    else if (microgrid_cfg.en_mains){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 1){
            if (_dido->info.dido_data.conn_sign == 1)
                return true;
        }  
    }
    return false;
}

static bool grid_condition_with_none(dev_info_all_t *var, int value, unsigned int pos){ // 此方案：一定是纯市电并网，(市电不可控制)
    // struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_mains == 1 && microgrid_cfg.en_diesel_generator == 0){
        if (microgrid_cfg.en_sts == 0 && microgrid_cfg.en_icb == 0){
            return true;
        }
    }
    return false;
}

static bool grid_condition_with_force(dev_info_all_t *var, int value, unsigned int pos){
    if (bit_get(microgrid_ctrl.cut_flag, pos)){
        return true;
    }
    return false;
}

static bool await_condition(dev_info_all_t *var, int value, unsigned int pos){ 	
    return true;
}

/*****************************************/
static bool await_abnormal_condition(dev_info_all_t *var, int value, unsigned int pos){
    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ return true; }

    if (microgrid_data.on_line == 0) { 
        return true; 
    }

    for (int i = 0 ; i < var->cabinet_info.num; i++)  //所有柜子都不能用 
	{
	    cabinet_inside_t *_cabinet_inside  = var->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0)
            return false; 
	}	
    return true;
}


static bool grid_abnormal_condition(dev_info_all_t *var, int value, unsigned int pos){
    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ return true; }

    if (microgrid_data.on_line == 0) { 
        return true; 
    }

    // 1. 并网断路器合闸超时、2. 负载断路器合闸超时（跟状态init动作相关）
    if (microgrid_abnormal.icb_abnormal == 1 || microgrid_abnormal.lcb_abnormal == 1){ return true; }

    for (int i = 0 ; i < var->cabinet_info.num; i++)
	{
	    cabinet_inside_t *_cabinet_inside  = var->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0)
            return false; 
	}	
    return true;
}

static bool offgrid_abnormal_condition(dev_info_all_t *var, int value, unsigned int pos){
    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ return true; }

    if (microgrid_data.on_line == 0) { 
        return true; 
    }

    // 1. 确认柴发关机超时、2. 确认并离网断路器分闸超时、3. 负载断路器分闸超时
    if (microgrid_abnormal.DG_abnormal == 2 || microgrid_abnormal.icb_abnormal == 2 || microgrid_abnormal.lcb_abnormal == 2){ return true; }

    for (int i = 0 ; i < var->cabinet_info.num; i++)
	{
	    cabinet_inside_t *_cabinet_inside  = var->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0)
            return false; 
	}	
    return true;
}

static bool cf_grid_abnormal_condition(dev_info_all_t *var, int value, unsigned int pos){
    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ return true; }

    if (microgrid_data.on_line == 0) { 
        return true; 
    }
 
    // 1. 确认柴发开机超时、2. 并网断路器合闸超时、3. 负载断路器合闸超时
    if (microgrid_abnormal.DG_abnormal == 1 || microgrid_abnormal.icb_abnormal == 1 || microgrid_abnormal.lcb_abnormal == 1){ return true; }

    for (int i = 0 ; i < var->cabinet_info.num; i++)
	{
	    cabinet_inside_t *_cabinet_inside  = var->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0)
            return false; 
	}	
    return true;
}

static bool init_grid_abnormal_condition(dev_info_all_t *var, int value, unsigned int pos){
    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ return true; } // 1. 主机状态异常

    if (microgrid_data.on_line == 0) {  // 2. 所有LC都离线，进入异常状态，某些场景下晚上光伏设备会离线，因此PV离线不作为异常判断，只需把pv_power刷新为0即可；
        return true; 
    }

    // 3. 动作超时异常，排查后需手动清除异常标志（点位）
    if (microgrid_abnormal.lcb_abnormal == 1){ return true; }

    // 4. 所有LC都不可用  
    for (int i = 0 ; i < var->cabinet_info.num; i++)
	{
	    cabinet_inside_t *_cabinet_inside  = var->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0)
            return false; 
	}	
    return true;
}

// ============ 某个动作超时，不能影响其他状态的切出 ============
static bool abnormal_grid_condition_perp(void){
    if (microgrid_abnormal.icb_abnormal == 1){
        micro_ac_log(LOG_WARNING, AC_ID_0008, NULL, IS_KEY, "并离网断路器合闸异常，不允许切市电并网!!!，请手动排查，并清除故障 icb_abnormal:%d", microgrid_abnormal.icb_abnormal); 
        return false; 
    }	
    return true;
}

static bool abnormal_cfgrid_condition_perp(void){
    if (microgrid_abnormal.DG_abnormal == 1 || microgrid_abnormal.icb_abnormal == 1){
        micro_ac_log(LOG_WARNING, AC_ID_0008, NULL, IS_KEY, "并离网断路器合闸异常或柴发启动异常，不允许切柴发并网!!!，请手动排查，并清除故障 icb_abnormal:%d DG_abnormal:%d", microgrid_abnormal.icb_abnormal, microgrid_abnormal.DG_abnormal); 
        return false; 
    }	
    return true;
}

static bool abnormal_offgrid_condition_perp(void){
    if (microgrid_abnormal.DG_abnormal == 2 || microgrid_abnormal.icb_abnormal == 2 || microgrid_abnormal.lcb_abnormal == 2){ 
        micro_ac_log(LOG_WARNING, AC_ID_0008, NULL, IS_KEY, "并离网断路器分闸异常或柴发停机异常或负载断路器分闸异常，不允许切离网!!!，请手动排查，并清除故障 icb_abnormal:%d DG_abnormal:%d lcb_abnormal:%d", microgrid_abnormal.icb_abnormal, microgrid_abnormal.DG_abnormal, microgrid_abnormal.lcb_abnormal); 
        return false; 
    }
    return true;
}

// 实际场景中，不存在市电并网直接切柴发并网，
// 带STS，柴发并网-->离网"短暂"-->市电并网
// 不带STS，柴发并网-->离网-->市电并网
/* ****************************************** "状态机"，状态切出，条件可添加 *****************start**********************/
static micr_condition_and_check_t grid_handover_detect[] = {
    {"异常状态",  STATE_ABNORMAL,  BIT_STATE_ABNORMAL,  LOGIC_OR, { {grid_abnormal_condition, 0},
                                                                    {NULL, 0} }, NULL }, // {NULL, 0} 结束符
    {"待机",     STATE_AWAIT,     BIT_STATE_OFF_GRID,   LOGIC_OR, {    {offgrid_condition_with_sts, 0}, 
                                                                        {offgrid_condition_with_cirbreak, 0}, 
                                                                        {offgrid_condition_with_none, 0},
                                                                        {offgrid_condition_with_force, 0}, 
                                                                        {NULL, 0} }, NULL },
    {"待机",     STATE_AWAIT,     BIT_STATE_CF_CONNECT_GRID,  LOGIC_OR, {   {cfgrid_condition_with_sts, 0}, 
                                                                            {cfgrid_condition_with_cirbreak, 0}, 
                                                                            {cfgrid_condition_with_none, 0}, 
                                                                            {cfgrid_condition_with_force, 0}, 
                                                                            {NULL, 0} }, NULL  },
};

static micr_condition_and_check_t offgrid_handover_detect[] = {
    {"异常状态", STATE_ABNORMAL, BIT_STATE_ABNORMAL, LOGIC_OR, { {offgrid_abnormal_condition, 0}, 
                                                                {NULL, 0} }, NULL  },
    {"待机",     STATE_AWAIT,   BIT_STATE_CONNECT_GRID,  LOGIC_OR, { {grid_condition_with_sts, 0}, 
                                                                    {grid_condition_with_cirbreak, 0}, 
                                                                    {grid_condition_with_none, 0}, 
                                                                    {grid_condition_with_force, 0}, 
                                                                    {NULL, 0} }, NULL  },
    {"待机",     STATE_AWAIT,   BIT_STATE_CF_CONNECT_GRID,  LOGIC_OR, { {cfgrid_condition_with_sts, 0}, 
                                                                        {cfgrid_condition_with_cirbreak, 0}, 
                                                                        {cfgrid_condition_with_none, 0},
                                                                        {cfgrid_condition_with_force, 0}, 
                                                                        {NULL, 0} }, NULL  },
};

static micr_condition_and_check_t cf_grid_handover_detect[] = {
    {"异常状态", STATE_ABNORMAL,  BIT_STATE_ABNORMAL,  LOGIC_OR, { {cf_grid_abnormal_condition, 0}, 
                                                                    {NULL, 0} }, NULL  },
    {"待机",     STATE_AWAIT,    BIT_STATE_CONNECT_GRID,   LOGIC_OR, {  {grid_condition_with_sts, 0}, 
                                                                        {grid_condition_with_cirbreak, 0}, 
                                                                        {grid_condition_with_none, 0}, 
                                                                        {grid_condition_with_force, 0}, 
                                                                        {NULL, 0} }, NULL  },
    {"待机",     STATE_AWAIT,   BIT_STATE_OFF_GRID,    LOGIC_OR, {  {offgrid_condition_with_sts, 0}, 
                                                                    {offgrid_condition_with_cirbreak, 0},
                                                                    {offgrid_condition_with_none, 0},
                                                                    {offgrid_condition_with_force, 0}, 
                                                                    {NULL, 0} }, NULL  },
};

static micr_condition_and_check_t await_handover_detect[] = { // 若所有状态都不满足，且没有异常，则待机等待 ~~"中间态"
    {"异常状态", STATE_ABNORMAL,  BIT_STATE_ABNORMAL,   LOGIC_OR, { {await_abnormal_condition, 0}, 
                                                                    {NULL, 0} }, NULL  },
    {"市电并网", STATE_CONNECT_GRID,  BIT_STATE_CONNECT_GRID,  LOGIC_OR, {  {grid_condition_with_sts, 0}, 
                                                                            {grid_condition_with_cirbreak, 0}, 
                                                                            {grid_condition_with_none, 0},
                                                                            {grid_condition_with_force, 0}, 
                                                                            {NULL, 0} }, NULL  },
    {"柴发并网", STATE_CF_CONNECT_GRID, BIT_STATE_CF_CONNECT_GRID, LOGIC_OR, {  {cfgrid_condition_with_sts, 0}, 
                                                                                {cfgrid_condition_with_cirbreak, 0},  
                                                                                {cfgrid_condition_with_none, 0},
                                                                                {cfgrid_condition_with_force, 0},  
                                                                                {NULL, 0} }, NULL  },
    {"离网",     STATE_OFF_GRID,   BIT_STATE_OFF_GRID, LOGIC_OR, {  {offgrid_condition_with_sts, 0}, 
                                                                    {offgrid_condition_with_cirbreak, 0}, 
                                                                    {offgrid_condition_with_none, 0},
                                                                    {offgrid_condition_with_force, 0},
                                                                    {NULL, 0} }, NULL  },
};

static micr_condition_and_check_t abnormal_handover_detect[] = {
    {"市电并网", STATE_CONNECT_GRID,  BIT_STATE_CONNECT_GRID,  LOGIC_OR, {  {grid_condition_with_sts, 0}, 
                                                                            {grid_condition_with_cirbreak, 0},  
                                                                            {grid_condition_with_none, 0},
                                                                            {grid_condition_with_force, 0}, 
                                                                            {NULL, 0} },  abnormal_grid_condition_perp }, // perp--检测切出的前置条件
    {"柴发并网", STATE_CF_CONNECT_GRID, BIT_STATE_CF_CONNECT_GRID,  LOGIC_OR, { {cfgrid_condition_with_sts, 0}, 
                                                                                {cfgrid_condition_with_cirbreak, 0}, 
                                                                                {cfgrid_condition_with_none, 0},
                                                                                {cfgrid_condition_with_force, 0}, 
                                                                                {NULL, 0} },   abnormal_cfgrid_condition_perp},
    {"离网",     STATE_OFF_GRID,   BIT_STATE_OFF_GRID,     LOGIC_OR, { {offgrid_condition_with_sts, 0}, 
                                                                        {offgrid_condition_with_cirbreak, 0}, 
                                                                        {offgrid_condition_with_none, 0},
                                                                        {offgrid_condition_with_force, 0},
                                                                        {NULL, 0} },  abnormal_offgrid_condition_perp},
};

static micr_condition_and_check_t init_handover_detect[] = {
    {"异常状态",  STATE_ABNORMAL,    BIT_STATE_ABNORMAL,      LOGIC_OR, { {init_grid_abnormal_condition, 0}, 
                                                                    {NULL, 0} }, NULL  },
    {"市电并网", STATE_CONNECT_GRID,  BIT_STATE_CONNECT_GRID,  LOGIC_OR, { {grid_condition_with_sts, 0}, 
                                                                            {grid_condition_with_cirbreak, 0},  
                                                                            {grid_condition_with_none, 0}, 
                                                                            {grid_condition_with_force, 0}, 
                                                                            {NULL, 0} }, NULL  },
    {"柴发并网", STATE_CF_CONNECT_GRID, BIT_STATE_CF_CONNECT_GRID,  LOGIC_OR, { {cfgrid_condition_with_sts, 0}, 
                                                                                {cfgrid_condition_with_cirbreak, 0}, 
                                                                                {cfgrid_condition_with_none, 0}, 
                                                                                {cfgrid_condition_with_force, 0}, 
                                                                                {NULL, 0} }, NULL  },
    {"离网",    STATE_OFF_GRID,    BIT_STATE_OFF_GRID,     LOGIC_OR, { {offgrid_condition_with_sts, 0}, 
                                                                        {offgrid_condition_with_cirbreak, 0},
                                                                        {offgrid_condition_with_none, 0}, 
                                                                        {offgrid_condition_with_force, 0},
                                                                        {NULL, 0} }, NULL  },
    {"待机",    STATE_AWAIT,     BIT_STATE_AWAIT,       LOGIC_OR, { {await_condition, 0}, 
                                                                    {NULL, 0} }, NULL  }  //上述条件都不满足，进入待机状态
};
/* *******************************************************************************************end**********************/
static bool check_conditions(micr_condition_and_check_t *check) {
    dev_info_all_t *var = get_dev_info_all_var();
    if (check->check_condi_perp == NULL) // 前置条件perp = NULL，直接判断切出条件即可
        CHECK_CONDITIONS(check, check->relation, check->pos);
    else{
        if (check->check_condi_perp())
            CHECK_CONDITIONS(check, check->relation, check->pos);
        else
            return false;
    }
}

static RELEVANCE_STATE micr_condition_check(micr_condition_and_check_t *micr_condition_and_check, int size, RELEVANCE_STATE state){
    Relevant_data_refresh();
    for (int i = 0; i < size; i++) { // 按顺序检测，返回切出状态"标识"，若未满足切出状态，则返回当前状态
        if (check_conditions(&micr_condition_and_check[i]) == true){
            micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "cute out state: %s", micr_condition_and_check[i].desc);
            return  micr_condition_and_check[i].state;
        }
    }
    return state;
}
/******************************************************** */
static void update_cf_switch(dev_info_all_t *var, int value)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_diesel_generator)
        atomic_store(&_dido->info.dido_ctrl.DG_ctrl, value);
}

static int chk_cf_switch(dev_info_all_t *var, int value)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];

    if(microgrid_cfg.en_diesel_generator == 0 || value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "DG sign :%d", _dido->info.dido_data.DG_sign);
    if(0 == value)//0: 停止  1:启动
    {
        if(_dido->info.dido_data.DG_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.DG_abnormal, DG_ABNORMAL, 2, DG_SIGN_OFF);
        return (_dido->info.dido_data.DG_sign == 0) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value)
    {
        if(_dido->info.dido_data.DG_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.DG_abnormal, DG_ABNORMAL, 1, DG_SIGN_ON);
        return (_dido->info.dido_data.DG_sign == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

static void update_pv_switch(dev_info_all_t *var, int value){
    if (microgrid_cfg.en_photovoltaic)
        atomic_store(&microgrid_ctrl.pv_exp_onoff, value);
}

static int chk_pv_switch(dev_info_all_t *var, int value)
{
    if(microgrid_cfg.en_photovoltaic == 0 || microgrid_ctrl.pv_isctrl == 1 || value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "pv status pv_on_statu :%d, pv_off_statu :%d", microgrid_data.pv_on_statu, microgrid_data.pv_off_statu);
    if(0 == value)//停机
    {
        if(microgrid_data.pv_off_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.pv_off_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value) //开机
    {
        if(microgrid_data.pv_on_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.pv_on_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

static void update_pcs_connect(dev_info_all_t *var, int value)
{
    int index = 0;

    if (microgrid_cfg.en_sts == 0){
        atomic_store(&microgrid_ctrl.Grid_offgrid, value);
        for(index = 0; index < var->cabinet_info.num; index++)
        {
            atomic_store(&var->cabinet_info.cabinet_inside[index]->cab_ctrl.connect, value);
        }
    }
}

static int chk_pcs_connect(dev_info_all_t *var, int value)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "pcs  grid_statu:%d, offgrid_statu :%d", microgrid_data.grid_statu, microgrid_data.offgrid_statu);
    if(value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    if(0 == value)//离网
    {
        if(microgrid_data.offgrid_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.offgrid_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value) //并网
    {
        if(microgrid_data.grid_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.grid_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

static void update_pcs_switch(dev_info_all_t *var, int value)
{
    int index = 0;
    atomic_store(&microgrid_ctrl.onoff, value);
    for(index = 0; index < var->cabinet_info.num; index++)
    {
        atomic_store(&var->cabinet_info.cabinet_inside[index]->cab_ctrl.onoff, value);
    }
}

static int chk_pcs_switch(dev_info_all_t *var, int value)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "pcs status stop :%d, run :%d", microgrid_data.off_statu, microgrid_data.on_statu);
    if(value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    if(value == 1 && microgrid_ctrl.auto_off == 1) return MICR_CONDITION_SKIP;
    if(0 == value)//停机
    {
        if(microgrid_data.off_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.off_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value) //开机
    {
        if(microgrid_data.on_statu == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        return (microgrid_data.on_statu == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

static void update_load_switch(dev_info_all_t *var, int value)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_lcb)
        atomic_store(&_dido->info.dido_ctrl.lcb_ctrl, value);
}

static int chk_load_switch(dev_info_all_t *var, int value)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];

    if(microgrid_cfg.en_lcb == 0 || value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "lcb sign :%d", _dido->info.dido_data.lcb_sign);
    if(0 == value) // 0: 断开  1:闭合
    {
        if(_dido->info.dido_data.lcb_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.lcb_abnormal, LCB_ABNORMAL, 2, LCB_SIGN_OFF);
        return (_dido->info.dido_data.lcb_sign == 0) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value)
    {
        if(_dido->info.dido_data.lcb_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.lcb_abnormal, LCB_ABNORMAL, 1, LCB_SIGN_ON);
        return (_dido->info.dido_data.lcb_sign == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

static void update_gd_switch(dev_info_all_t *var, int value) // 并离网断路器没有市电/柴发时，会自动分闸，只需确认分闸就行；但合闸需要EMS自己控制，(需确认PCS并网后，再合闸)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];
    if (microgrid_cfg.en_icb)
        atomic_store(&_dido->info.dido_ctrl.icb_ctrl, value);
}

static int chk_gd_switch(dev_info_all_t *var, int value)
{
    struct _dido_t * _dido = &var->dido.dido_param[0];

    if(microgrid_cfg.en_icb == 0 || value == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "icb sign :%d", _dido->info.dido_data.icb_sign);
    if(0 == value)//分闸
    {
        if(_dido->info.dido_data.icb_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.icb_abnormal, ICB_ABNORMAL, 2, ICB_SIGN_OFF);
        return (_dido->info.dido_data.icb_sign == 0) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    else if (1 == value) //合闸
    {
        if(_dido->info.dido_data.icb_sign == MICR_ACTION_TYPE_INIT) return MICR_CONDITION_SKIP;
        check_action_timeout(&microgrid_abnormal.icb_abnormal, ICB_ABNORMAL, 1, ICB_SIGN_ON);
        return (_dido->info.dido_data.icb_sign == 1) ? MICR_CONDITION_OK : MICR_CONDITION_NO_MATCH;
    }
    return MICR_CONDITION_NO_MATCH;
}

// 注意: 1. 没有使能对应的开关会自动跳过检查  2. 检查函数入参-1 ，也会跳过检查
/*grid ****************************************** "状态机"，进入状态执行策略逻辑前必须要执行的动作 按顺序执行，可添加 ********************************start**********************/
static micr_action_and_check_t grid_init_actions[] = {
    //{"确认并离网断路器分闸", update_gd_switch,         0,      chk_gd_switch,                      0},
    {"PCS关机", update_pcs_switch,                   0,      chk_pcs_switch,                      0},
    {"PCS并网", update_pcs_connect,                  1,      chk_pcs_connect,                     1},
    {"并离网断路器合闸", update_gd_switch,            1,      chk_gd_switch,                       1},
    {"PCS开机", update_pcs_switch,                   1,      chk_pcs_switch,                      1},
    {"PV开机",  update_pv_switch,                    1,      chk_pv_switch,                       1},
    {"接通负载",update_load_switch,                  1,      chk_load_switch,                     1}
};

static micr_action_and_check_t grid_init_actions_sts[] = {
    {"PCS开机", update_pcs_switch,                   1,      chk_pcs_switch,                      1},
    {"PV开机",  update_pv_switch,                    1,      chk_pv_switch,                       1},
    {"接通负载",update_load_switch,                  1,      chk_load_switch,                     1}
};
/* offgrid ********************************************/
static micr_action_and_check_t offgrid_init_actions[] = {
    {"确认CF关机", update_cf_switch,                   0,      chk_cf_switch,                     0},
    {"确认并离网断路器分闸", update_gd_switch,          0,      chk_gd_switch,                      0}, //参数： -1表示不检查，0表示分闸，1表示合闸，其他值返回NO_MATCH,
    {"PCS关机", update_pcs_switch,                     0,      chk_pcs_switch,                     0},
    {"PCS离网", update_pcs_connect,                    0,      chk_pcs_connect,                    0},
    {"PCS开机", update_pcs_switch,                     1,      chk_pcs_switch,                     1},
    {"PV开机",  update_pv_switch,                      1,      chk_pv_switch,                      1}
};

static micr_action_and_check_t offgrid_init_actions_sts[] = { //确保PCS、PV开机
    {"PCS开机", update_pcs_switch,                     1,      chk_pcs_switch,                     1},
    {"PV开机",  update_pv_switch,                      1,      chk_pv_switch,                      1}
};
/* cf_grid ********************************************/
static micr_action_and_check_t cf_grid_init_actions[] = {
    //{"确认并离网断路器分闸", update_gd_switch,        0,      chk_gd_switch,                     0},
    {"PCS关机", update_pcs_switch,                   0,      chk_pcs_switch,                    0},
    {"PCS并网", update_pcs_connect,                  1,      chk_pcs_connect,                   1},
    {"PV关机", update_pv_switch,                     0,      chk_pv_switch,                     0},
    {"确认CF开机", update_cf_switch,                 1,      chk_cf_switch,                     1}, // 1.使能STS或并离网断路器时，离网行为中可先开启柴发，此处只需确认柴发开机即可 2.不使能STS和并离网断路器时，则需要强切，离网行为中不能开柴发，置位强切标志后，柴发在此处开启
    {"并离网断路器合闸", update_gd_switch,            1,      chk_gd_switch,                     1},
    {"PCS开机", update_pcs_switch,                   1,      chk_pcs_switch,                    1},
    {"接通负载", update_load_switch,                 1,      chk_load_switch,                   1}
};

static micr_action_and_check_t cf_grid_init_actions_sts[] = {
    {"PV关机", update_pv_switch,                     0,      chk_pv_switch,                     0},
    {"确认CF开机", update_cf_switch,                 1,      chk_cf_switch,                     1},
    {"PCS开机", update_pcs_switch,                   1,      chk_pcs_switch,                    1},
    {"接通负载",update_load_switch,                  1,      chk_load_switch,                   1}
};
/* await ********************************************/
static micr_action_and_check_t await_init_actions[] = {
    {"PV关机", update_pv_switch,                     0,      chk_pv_switch,                     0},
    {"PCS关机", update_pcs_switch,                   0,      chk_pcs_switch,                    0},
};

static micr_action_and_check_t await_init_actions_sts[] = {
};
/* abnormal ********************************************/
static micr_action_and_check_t abnormal_init_actions[] = {
    {"PV关机", update_pv_switch,                     0,      chk_pv_switch,                     -1},
    {"PCS关机", update_pcs_switch,                   0,      chk_pcs_switch,                    -1},
    {"断开负载", update_load_switch,                 0,      chk_load_switch,                   -1}
};
/* init ********************************************/
static micr_action_and_check_t init_actions[] = { // 各个设备准备好，等待进入状态
    {"PCS开机", update_pcs_switch,                   1,      chk_pcs_switch,                    1},
    {"PV开机",  update_pv_switch,                    1,      chk_pv_switch,                     1},
    {"接通负载",update_load_switch,                  1,      chk_load_switch,                   1}
};
/******************************************* "状态机"，进入状态执行策略逻辑前必须要执行的动作 ****************************************end**********************/
static int excute_action_steps(micr_action_and_check_t *action_steps, int *action_step_idx, int action_steps_max){
    int res = 0;
    char result[1024] = "<";
    if (action_steps == NULL) return res;

    static int idx = -1;
    static micr_action_and_check_t *p = NULL;
    if (p == NULL){
        p = action_steps;
    }
    else{ // 状态切换，idx = -1
        if (action_steps != p){
            p = action_steps;
            idx = -1;
        }
    }
#if 1
    for (int i = 0; i < action_steps_max; i++) {
        micr_action_and_check_t *step = &action_steps[i];
        char tmp[128] = "";
        snprintf(tmp, sizeof(tmp), "%d:%s ", i, step->desc);
        strncat(result, tmp, sizeof(result) - strlen(result) - 1);
    }
    strncat(result, ">", sizeof(result) - strlen(result) - 1);
#endif
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    if(*action_step_idx < action_steps_max)
    {
        if (*action_step_idx != idx){
            idx = *action_step_idx;
            time(&startTime); // action execute time
        }
        micr_action_and_check_t *step = &action_steps[*action_step_idx];
        step->update_cb(_dev_info_all, step->update_param);
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "当前：%d[%s]， 总步骤: %d 等待就绪...", *action_step_idx, step->desc, action_steps_max);
        if(Relevant_data_refresh() == 0)//>>> 刷新数据源
        {
            int ret = step->condition_cb(_dev_info_all, step->condition_param);
            //That callback of condition return zero means this check passed and to do next step.
            if(ret == MICR_CONDITION_OK || ret == MICR_CONDITION_SKIP) 
            {
                if(ret == MICR_CONDITION_SKIP)
                    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "current action: %s, ignore step, invalid feedback data, go to step: [%d]!", step->desc, *action_step_idx);
                (*action_step_idx)++;
                micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "current action: %s, go to step: [%d]...", step->desc, *action_step_idx);
            }
        }
    }else
        res = 1; //符合状态进入条件后，执行后续策略逻辑 return 1;
    return res;
}

static void inf_printf(void){

    dev_set_dev_tag_float(DEV_NO_EMS, TOTAL_PV_POWER, microgrid_data.pv_power);
    dev_set_dev_tag_float(DEV_NO_EMS, TOTAL_PCS_POWER, microgrid_data.pcs_power);
    dev_set_dev_tag_float(DEV_NO_EMS, AVER_SOC, microgrid_data.SOC_average);
#if 0
    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "关口表功率 = %lf, 储能总功率 = %lf, 光伏总功率 = %lf, 负载功率（仅参考，不参与算法计算） = %lf, 多柜soc最大值 = %lf, 多柜soc平均值 = %lf, 多柜soc最小值 = %lf,", microgrid_data.grid_power,
                microgrid_data.pcs_power, microgrid_data.pv_power, microgrid_data.load_power, microgrid_data.SOC_ceiling, microgrid_data.SOC_average, microgrid_data.SOC_floor);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "微网配置参数 ：：：");
    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "---------------------------------------------------------------------");
    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "SOC上限<并网> = %lf, SOC下限<并网> = %lf, SOC上限<离网> = %lf,  SOC下限<离网> = %lf,  SOC上限回差 = %lf, SOC下限回差 = %lf ", microgrid_ctrl.SOC_max_combin,
                microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_netdead, microgrid_ctrl.SOC_min_netdead, microgrid_ctrl.SOCmaxReturnDiff, microgrid_ctrl.SOCminReturnDiff);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "光伏输出最大功率 = %lf, 光伏增长斜率 = %d, 光伏控制模式(0: 功率, 1：百分比) = %d, 黑夜死区（默认：180秒） = %d, 光伏是否可控(0: 可控, 1：不可控) = %d, 系统最大充电功率（配置） = %lf, 系统最大放电功率（配置） = %lf", microgrid_ctrl.pvMax, microgrid_ctrl.pv_km, microgrid_ctrl.pv_mode, microgrid_ctrl.dead_night, microgrid_ctrl.pv_isctrl,
                microgrid_ctrl.chargeMaxPower, microgrid_ctrl.dischargeMaxPower);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "是否使能防逆流 = %d, 防逆流余量 = %lf, 是否负荷跟踪 = %d, 负荷跟踪系数 = %lf ", microgrid_ctrl.en_anti_reflux, 
                microgrid_ctrl.anti_reflux, microgrid_ctrl.EnTraceLoad, microgrid_ctrl.TraceLoad);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "是否使能高压侧变压器保护(0: 禁用 1：高压侧变压器保护 2：需量保护) = %d, 高压侧变压器容量 = %lf, 高压侧容量控制系数 = %d, 需量保护(0: 禁用 1：高压侧变压器保护 2：需量保护) = %d, 需量回差 = %lf, 是否使能低压侧变压器保护 = %d, 低压侧变压器容量 = %d, 低压侧容量控制系数 = %f ",  microgrid_ctrl.EnProtectTransf, 
                microgrid_ctrl.Pmlmax, microgrid_ctrl.K1, microgrid_ctrl.EnProtectTransf, microgrid_ctrl.PmlmaxDiff, microgrid_ctrl.EnProtectTrasLV, microgrid_ctrl.PLVmlmax, microgrid_ctrl.k4);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "使能 （峰电）- 逆流转充 = %d, 使能 （谷电）- 超容转放 = %d", microgrid_ctrl.en_ac_d2c, microgrid_ctrl.en_ac_c2d);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "柴发额定容量 = %lf, 柴发启动SOC阈值 = %lf, 柴发容量回差 = %lf", microgrid_ctrl.dg_rated_power, 
                microgrid_ctrl.dg_boot_soc, microgrid_ctrl.DgDiff);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "DOD 保护使能开关 = %d, bms功率限制使能开关 = %d", microgrid_ctrl.en_DOD, 
                microgrid_ctrl.en_bms_power_limit);

    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "动作超时时间（默认：120秒） = %d", microgrid_ctrl.action_timeout);
    micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "---------------------------------------------------------------------");
#endif
#if 1
    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "关口表功率 = %lf, 储能总功率 = %lf, 光伏总功率 = %lf, 负载功率（仅参考，不参与算法计算） = %lf, 多柜soc最大值 = %lf, 多柜soc平均值 = %lf, 多柜soc最小值 = %lf", microgrid_data.grid_power,
                microgrid_data.pcs_power, microgrid_data.pv_power, microgrid_data.load_power, microgrid_data.SOC_ceiling, microgrid_data.SOC_average, microgrid_data.SOC_floor);

    micro_ac_log(LOG_INFO, AC_ID_0004, NULL, IS_KEY, "微网配置参数 ：：：");
    micro_ac_log(LOG_INFO, AC_ID_0005, NULL, IS_KEY, "---------------------------------------------------------------------");
    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "SOC上限<并网> = %lf, SOC下限<并网> = %lf, SOC上限<离网> = %lf,  SOC下限<离网> = %lf,  SOC上限回差 = %lf, SOC下限回差 = %lf ", microgrid_ctrl.SOC_max_combin,
                microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_netdead, microgrid_ctrl.SOC_min_netdead, microgrid_ctrl.SOCmaxReturnDiff, microgrid_ctrl.SOCminReturnDiff);
    
    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "光伏输出最大功率 = %lf, 光伏增长斜率 = %d, 光伏控制模式(0: 功率, 1：百分比) = %d, 黑夜死区（默认：180秒） = %d, 光伏是否可控(0: 可控, 1：不可控) = %d, 系统最大充电功率（配置） = %lf, 系统最大放电功率（配置） = %lf ", microgrid_ctrl.pvMax, microgrid_ctrl.pv_km, microgrid_ctrl.pv_mode, microgrid_ctrl.dead_night, microgrid_ctrl.pv_isctrl,
                microgrid_ctrl.chargeMaxPower, microgrid_ctrl.dischargeMaxPower);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "是否使能防逆流 = %d, 防逆流余量 = %lf, 是否负荷跟踪 = %d, 负荷跟踪系数 = %lf ", microgrid_ctrl.en_anti_reflux, 
                microgrid_ctrl.anti_reflux, microgrid_ctrl.EnTraceLoad, microgrid_ctrl.TraceLoad);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "是否使能高压侧变压器保护(0: 禁用 1：高压侧变压器保护 2：需量保护) = %d, 高压侧变压器容量 = %lf, 高压侧容量控制系数 = %d, 需量保护(0: 禁用 1：高压侧变压器保护 2：需量保护) = %d, 需量回差 = %lf, 是否使能低压侧变压器保护 = %d, 低压侧变压器容量 = %d, 低压侧容量控制系数 = %f ",  microgrid_ctrl.EnProtectTransf, 
                microgrid_ctrl.Pmlmax, microgrid_ctrl.K1, microgrid_ctrl.EnProtectTransf, microgrid_ctrl.PmlmaxDiff, microgrid_ctrl.EnProtectTrasLV, microgrid_ctrl.PLVmlmax, microgrid_ctrl.k4);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "使能 （峰电）- 逆流转充 = %d, 使能 （谷电）- 超容转放 = %d ", microgrid_ctrl.en_ac_d2c, microgrid_ctrl.en_ac_c2d);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "柴发额定容量 = %lf, 柴发启动SOC阈值 = %lf, 柴发容量回差 = %lf ", microgrid_ctrl.dg_rated_power, 
                microgrid_ctrl.dg_boot_soc, microgrid_ctrl.DgDiff);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "DOD 保护使能开关 = %d, bms功率限制使能开关 = %d ", microgrid_ctrl.en_DOD, 
                microgrid_ctrl.en_bms_power_limit);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "动作超时时间（默认：120秒） = %d ", microgrid_ctrl.action_timeout);
    micro_ac_log(LOG_INFO, AC_ID_0006, NULL, IS_KEY, "---------------------------------------------------------------------\n");
    micro_ac_log(LOG_INFO, AC_ID_0007, NULL, IS_KEY, "\n \n");
#endif
}

static int chargefull = 0, dischargefull = 0;
/*
static void ac_fush_battery_status_average(double SOC_min_combin, double SOC_max_combin) { // 平均值  刷新总的电池状态，状态：放空、可充可放、满充
    double soc_max_back = SOC_max_combin - microgrid_ctrl.SOCmaxReturnDiff;
    double soc_min_back = SOC_min_combin + microgrid_ctrl.SOCminReturnDiff;

    if (microgrid_data.SOC_average < soc_max_back) {
        chargefull = 0;
        microgrid_data.battery_sta = STATE_OR;
    } else if (microgrid_data.SOC_average >= SOC_max_combin || chargefull == 1) { // 95 90
        chargefull = 1; // 满充
        microgrid_data.battery_sta = STATE_FULL;
        micro_ac_log(LOG_NOTICE, AC_ID_0032, NOT_KEY, "Full charge, battery_sta: %d!!!", microgrid_data.battery_sta);
        return;
    }

    if (microgrid_data.SOC_average > soc_min_back) {
        dischargefull = 0;
        microgrid_data.battery_sta = STATE_OR;
    } else if (microgrid_data.SOC_average <= SOC_min_combin || dischargefull == 1) { // 5 10
        dischargefull = 1; // 放空
        microgrid_data.battery_sta = STATE_EMPTY;
        micro_ac_log(LOG_NOTICE, AC_ID_0032, NOT_KEY, "Empty discharge, battery_sta: %d!!!", microgrid_data.battery_sta);
    }
}
*/

// 此函数专为离网逻辑服务，离网PCS自适应，EMS不能控制功率，为避免多柜电池过充/过放， 因此更新电池状态时，采用边缘值判断
static void ac_fush_battery_status_edge(double SOC_min_combin, double SOC_max_combin) { // 边缘值  刷新总的电池状态，状态：放空、可充可放、满充
    double soc_max_back = SOC_max_combin - microgrid_ctrl.SOCmaxReturnDiff;
    double soc_min_back = SOC_min_combin + microgrid_ctrl.SOCminReturnDiff;

    if (microgrid_data.SOC_ceiling < soc_max_back) {
        chargefull = 0;
        microgrid_data.battery_sta = STATE_OR;
    } else if (microgrid_data.SOC_ceiling >= SOC_max_combin || chargefull == 1) { // 95 90
        chargefull = 1; // 满充
        microgrid_data.battery_sta = STATE_FULL;
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "满充，电池状态: %d", microgrid_data.battery_sta);
        return;
    }

    if (microgrid_data.SOC_floor > soc_min_back) {
        dischargefull = 0;
        microgrid_data.battery_sta = STATE_OR;
    } else if (microgrid_data.SOC_floor <= SOC_min_combin || dischargefull == 1) { // 5 10
        dischargefull = 1; // 放空
        microgrid_data.battery_sta = STATE_EMPTY;
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "放空，电池状态: %d", microgrid_data.battery_sta);
    }
}

static void cabinet_fush_battery_status(double SOC_min, double SOC_max, cabinet_inside_t *cabinet_inside, battery_flag_t *battery_flag) { // 刷新每个柜子的电池状态，状态：放空、可充可放、满充
    double soc_max_back = SOC_max - microgrid_ctrl.SOCmaxReturnDiff;
    double soc_min_back = SOC_min + microgrid_ctrl.SOCminReturnDiff;
    double SOC = cabinet_inside->cab_data.SOC_average;

    if (SOC < soc_max_back) {
        battery_flag->chargefull = 0;
        cabinet_inside->cab_data.battery_sta = STATE_OR;
    } 
    else if (SOC >= SOC_max || battery_flag->chargefull == 1) {  // 95 90 
        battery_flag->chargefull = 1; // 满充
        cabinet_inside->cab_data.battery_sta = STATE_FULL;
        micro_ac_log(LOG_NOTICE, AC_ID_0030, cabinet_inside->no, IS_KEY, "Cab %s, SOC:%lf, 满充, 电池状态: %d!!!", cabinet_inside->no, SOC, cabinet_inside->cab_data.battery_sta);
        return;
    }

    if (SOC > soc_min_back) {
        battery_flag->dischargefull = 0;
        cabinet_inside->cab_data.battery_sta = STATE_OR;
    } 
    else if (SOC <= SOC_min || battery_flag->dischargefull == 1) { // 5 10
        battery_flag->dischargefull = 1; // 放空
        cabinet_inside->cab_data.battery_sta = STATE_EMPTY;
        micro_ac_log(LOG_NOTICE, AC_ID_0030, cabinet_inside->no, IS_KEY, "Cab %s, SOC:%lf, 放空, 电池状态: %d!!!", cabinet_inside->no, SOC, cabinet_inside->cab_data.battery_sta);
    }
}

// 根据SOC上下限回差，限制BMS的最大充放电能力，反馈给上层业务逻辑
// "上层"：逻辑上快满充、放空时，'预干预'最大放电功率限制，使调整更加平滑，当储能充满出现断崖式曲线时 防止 光伏来不及调节时导致逆流 "下层"：根据lc反馈的当前最大可充可放功率和柜子状态（是否可用）、柜内电池状态，再次进行功率限制
static int cabinet_accord_soc_cal_power(double SOC_min, double SOC_max, cabinet_inside_t *cabinet_inside, battery_flag_t *battery_flag) {
    
    double char_difference = 1, dischar_difference = 1;
    double SOC = cabinet_inside->cab_data.SOC_average;

    /** 1. 根据SOC'预干预'最大充放电功率限制 **/
    // 并离、离网的SOC回差，公用一套参数 "SOCmaxErr" "SOCminErr"
    cabinet_fush_battery_status(SOC_min, SOC_max, cabinet_inside, battery_flag);

    if (cabinet_inside->cab_data.battery_sta == STATE_EMPTY) {
        dischar_difference = 0;
    }
    else{
        if (SOC <= (SOC_min + microgrid_ctrl.SOCminReturnDiff)) { // 10 <-- 15 ~~'预干预'
            dischar_difference = (SOC - SOC_min) / microgrid_ctrl.SOCminReturnDiff;
            dischar_difference = dischar_difference < 0 ? 0 : dischar_difference;
            micro_ac_log(LOG_NOTICE, AC_ID_0029, cabinet_inside->no, IS_KEY, "Cab %s, SOC过放保护:%lf 占比: %f", cabinet_inside->no, cabinet_inside->cab_data.SOC_average, dischar_difference);
        } 
    }
    if (cabinet_inside->cab_data.battery_sta == STATE_FULL) {
        char_difference = 0;
    }
    else{
        if (SOC >= (SOC_max - microgrid_ctrl.SOCmaxReturnDiff)) { // 90 --> 95 ~~'预干预'
            char_difference = (SOC_max - SOC) / microgrid_ctrl.SOCmaxReturnDiff;
            char_difference = char_difference < 0 ? 0 : char_difference;
            micro_ac_log(LOG_NOTICE, AC_ID_0029, cabinet_inside->no, IS_KEY, "Cab %s, SOC过充保护:%lf 占比: %f", cabinet_inside->no, cabinet_inside->cab_data.SOC_average, char_difference);
        }
    }

    if (char_difference <= 0.01)  char_difference = 0; // 精度调整
    if (dischar_difference <= 0.01)  dischar_difference = 0;

#if 1
    // 在快"充满放空"时，SOC一般不是线性变化，而是以0.5或者1\1.5为单位减小 或 增加，防止PCS放电或者充电功率出现阶梯式曲线，此处模拟一个衰减过程，使PCS的充放电功率曲线过度更平滑
    double target_power = 0, tmp = 0;
    if (char_difference == 1 || char_difference == 0){
        cabinet_inside->cab_ctrl.pcs_charge_max_set = cabinet_inside->cab_ctrl.charge_max_cfg * char_difference;          // 上层'预干预'PCS最大充电功率限制-->最大充电功率（配置）
    }
    else{
        target_power = cabinet_inside->cab_ctrl.charge_max_cfg * char_difference;
        tmp = (target_power * 100 / 100 - cabinet_inside->cab_ctrl.pcs_charge_max_set) * SOC_KM;
        cabinet_inside->cab_ctrl.pcs_charge_max_set = tmp + cabinet_inside->cab_ctrl.pcs_charge_max_set;        
    }
    if (dischar_difference == 1 || dischar_difference == 0){
        cabinet_inside->cab_ctrl.pcs_discharge_max_set = cabinet_inside->cab_ctrl.discharge_max_cfg * dischar_difference; // 上层'预干预'PCS最大放电功率限制-->最大放电功率（配置）
    }
    else{
        target_power = cabinet_inside->cab_ctrl.discharge_max_cfg * dischar_difference;
        tmp = (target_power * 100 / 100 - cabinet_inside->cab_ctrl.pcs_discharge_max_set) * SOC_KM;
        cabinet_inside->cab_ctrl.pcs_discharge_max_set = tmp + cabinet_inside->cab_ctrl.pcs_discharge_max_set;    
    }
    micro_ac_log(LOG_INFO, AC_ID_0028, cabinet_inside->no, IS_KEY,  "根据SOC限制最大充放电功率： Cab %s, [最大支持充电功率:%lf，配置的最大充电功率:%lf], [最大支持放电功率:%lf，配置的最大放电功率:%lf]", cabinet_inside->no, 
                    cabinet_inside->cab_ctrl.pcs_charge_max_set, cabinet_inside->cab_ctrl.charge_max_cfg, 
                    cabinet_inside->cab_ctrl.pcs_discharge_max_set, cabinet_inside->cab_ctrl.discharge_max_cfg);
#endif

    /** 2. BMS功率限制 **/
    if (microgrid_ctrl.en_bms_power_limit){
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "使能BMS功率限制!!!");
        
        micro_ac_log(LOG_INFO, AC_ID_0027, cabinet_inside->no, IS_KEY,  "Cab:%s 充电 [最大支持充电功率:%f, bms限制功率:%f]", cabinet_inside->no, cabinet_inside->cab_ctrl.pcs_charge_max_set, cabinet_inside->cab_ctrl.pcs_charge_max_actual);
        cabinet_inside->cab_ctrl.pcs_charge_max_set = (cabinet_inside->cab_ctrl.pcs_charge_max_set > cabinet_inside->cab_ctrl.pcs_charge_max_actual) ? cabinet_inside->cab_ctrl.pcs_charge_max_set : cabinet_inside->cab_ctrl.pcs_charge_max_actual;

        micro_ac_log(LOG_INFO, AC_ID_0026, cabinet_inside->no, IS_KEY,  "Cab:%s 放电 [最大支持放电功率:%f, bms限制功率:%f]", cabinet_inside->no, cabinet_inside->cab_ctrl.pcs_discharge_max_set, cabinet_inside->cab_ctrl.pcs_discharge_max_actual);
        cabinet_inside->cab_ctrl.pcs_discharge_max_set = (cabinet_inside->cab_ctrl.pcs_discharge_max_set < cabinet_inside->cab_ctrl.pcs_discharge_max_actual) ? cabinet_inside->cab_ctrl.pcs_discharge_max_set : cabinet_inside->cab_ctrl.pcs_discharge_max_actual;
    }

    // final
    micro_ac_log(LOG_NOTICE, AC_ID_0025, cabinet_inside->no, IS_KEY, "Cab %s 最终功率限制： 当前 最大支持充电功率: %lf, 最大支持放电功率: %lf", cabinet_inside->no, 
                    cabinet_inside->cab_ctrl.pcs_charge_max_set, cabinet_inside->cab_ctrl.pcs_discharge_max_set);
    return 0;
}

// 根据SOC上下限动态调整BMS的最大可充可放功率，进入回差范围后，根据SOC实际状态来设置衰减值，直至0功率，在解除满充、放空状态后，此值才可恢复
static void accord_soc_cal_supportpower(double SOC_min, double SOC_max){

    double charge_max_set = 0;
    double discharge_max_set = 0;
    dev_info_all_t *var = get_dev_info_all_var();

    // '预干预'最大放电功率限制
    for (int i = 0; i < var->cabinet_info.num; i++) {
        cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];
        cabinet_accord_soc_cal_power(SOC_min, SOC_max, cabinet_inside, &battery_flag[i]);
    }

    double tou_power = microgrid_ctrl.current_tou_info ? microgrid_ctrl.current_tou_info->Power : 0;

    for (int i = 0; i < var->cabinet_info.num; i++) {
        cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];
        if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_char == 0) {
            charge_max_set += cabinet_inside->cab_ctrl.pcs_charge_max_set;
        }
        if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_dischar == 0) {
            discharge_max_set += cabinet_inside->cab_ctrl.pcs_discharge_max_set;
        }
    }
    microgrid_ctrl.charge_max_set = charge_max_set; // 储能实际能消纳的功率，一般指充电功率，放电功率暂时不用，防止光伏发电太大，储能消纳不了，导致逆流
    microgrid_ctrl.discharge_max_set = discharge_max_set;
    if (tou_power < 0)
        microgrid_ctrl.charge_max_set = MAX(charge_max_set, tou_power);
    if (tou_power > 0)
        microgrid_ctrl.discharge_max_set = MIN(discharge_max_set, tou_power);
    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "系统总功率： 当前 最大支持充电功率: %lf 最大支持放电功率: %lf", microgrid_ctrl.charge_max_set, microgrid_ctrl.discharge_max_set);
#if 1
    ac_fush_battery_status_edge(SOC_min, SOC_max); // server for off_grid
#endif
}

static void adjust_to_target(double target, double pcs_power) {
    if (microgrid_ctrl.EnPvPrectrl){
        atomic_store(&microgrid_ctrl.pv_exp_power, target);
        atomic_store(&microgrid_ctrl.pcs_exp_power, pcs_power);
    }
    else{ // 禁用光伏精细化控制
        double current = atomic_load(&microgrid_ctrl.pv_exp_power); // current_set PV 

        double km = DOWN_PV_KM;
        if (target > current) 
            km = microgrid_ctrl.pv_km == 0 ? UP_PV_KM : (double)microgrid_ctrl.pv_km/100;

        double tmp = 0;
        double poor = target * 100 / 100 - current;
        if (fabs(poor) < 5.0) { // 直接收敛到目标值
            tmp = target;
        } 
        else {
            tmp = current + poor * km;
        }
        micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "pv_target_power::: [%lf], tmp %f = current %f + %f, km: %f", target, tmp, current, poor * km, km);

        atomic_store(&microgrid_ctrl.pv_exp_power, tmp);
        atomic_store(&microgrid_ctrl.pcs_exp_power, pcs_power);        
    }
}

// 光伏 功率/百分比 分配：mode:  0: 功率分配，1: 百分比分配
static void cal_and_set_pv_power(dev_info_all_t *var) {
    double pv_exp_power = atomic_load(&microgrid_ctrl.pv_exp_power);

    if (microgrid_ctrl.EnPvPrectrl != 0){ // 禁用光伏精细化控制
        double _pvMax = 0, _scale = 0;
        for (int i = 0; i < var->pv.num; i++) 
        {
            struct _pv_t *pv = &(var->pv.pv_param[i]);

            if (pv->info.pv_data.on_line){
                _pvMax += microgrid_ctrl.pvMax * pv->info.pv_cfg.scale;
                _scale += pv->info.pv_cfg.scale;
            }
        }

        for (int i = 0 ; i < var->pv.num; i++){
            if (microgrid_ctrl.pv_mode == 0){ // 动态功率分配
                double power = 0;
                if (_scale && var->pv.pv_param[i].info.pv_data.on_line){
                    power = pv_exp_power * var->pv.pv_param[i].info.pv_cfg.scale / _scale;
                }
                power = power > (microgrid_ctrl.pvMax * var->pv.pv_param[i].info.pv_cfg.scale) ? (microgrid_ctrl.pvMax * var->pv.pv_param[i].info.pv_cfg.scale) : power;
                
                atomic_store(&var->pv.pv_param[i].info.pv_ctrl.power_set, power);
                micro_ac_log(LOG_NOTICE, AC_ID_0024, var->pv.pv_param[i].no, IS_KEY, "光伏：Pv no: %s, 比例: %f, 设置功率 :%lf ", var->pv.pv_param[i].no, var->pv.pv_param[i].info.pv_cfg.scale, var->pv.pv_param[i].info.pv_ctrl.power_set); 
            }
            else{
                double percent = 0;
                if (_pvMax && var->pv.pv_param[i].info.pv_data.on_line){
                    percent = (double)pv_exp_power / _pvMax * 100;
                }
                if (percent > 100) percent = 100.0f;
                else if (percent < 0) percent = 0.0f;

                atomic_store(&var->pv.pv_param[i].info.pv_ctrl.power_set, percent);
                micro_ac_log(LOG_NOTICE, AC_ID_0024, var->pv.pv_param[i].no, IS_KEY, "光伏：Pv no: %s, 比例: %f, 设置百分比 :%lf ", var->pv.pv_param[i].no, var->pv.pv_param[i].info.pv_cfg.scale, var->pv.pv_param[i].info.pv_ctrl.power_set); 
            }
        }
    }
}

// 功率再分配：根据柜子实际是否可用、以及充满、放空状态，重新计算scale，进而计算每个柜子合理的功率分配值
static void cal_scale_and_set_lc_power(dev_info_all_t *var) {
    double pcs_exp_power = atomic_load(&microgrid_ctrl.pcs_exp_power);
    dev_set_dev_tag_float(DEV_NO_EMS, EXPECT_ACT_POWER, pcs_exp_power); // 主从模式，DOD保护在lc上，此处  期望功率=LC输入功率
    dev_set_dev_tag_float(DEV_NO_EMS, LOCAL_CTRL_POWER, pcs_exp_power);

    double scale = 0;
    double pcs_discharge_max_set = 0, pcs_charge_max_set = 0;

    for (int i = 0; i < var->cabinet_info.num; i++) { // 功率再分配：根据柜子实际是否可用、以及充满、放空状态，重新计算scale，进而计算每个柜子合理的功率分配值
        cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];

        if (pcs_exp_power > 0){ // 放电
            if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_dischar == 0 && cabinet_inside->cab_data.battery_sta != STATE_EMPTY) {
                scale += cabinet_inside->cab_cfg.scale;
                pcs_discharge_max_set += cabinet_inside->cab_ctrl.pcs_discharge_max_set;
            }
        }
        else if (pcs_exp_power < 0){
            if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_char == 0 && cabinet_inside->cab_data.battery_sta != STATE_FULL) {
                scale += cabinet_inside->cab_cfg.scale;
                pcs_charge_max_set += cabinet_inside->cab_ctrl.pcs_charge_max_set;
            }
        }
        else{
            if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0) {
                scale += cabinet_inside->cab_cfg.scale;
            }           
        }       
    }
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "real static scale sum: %lf, pcs_exp_power: %lf", scale, pcs_exp_power);

    if (scale == 0 || pcs_exp_power == 0){
        for (int i = 0 ; i < var->cabinet_info.num; i++){
            atomic_store(&var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, 0);
            // 分相模式下同时清零各相功率
            for (int phase = 0; phase < PHASE_MAX; phase++) {
                var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_phasepower[phase] = 0;
            }
        }
    }
    else{
        // 此处根据柜子是否可用、禁充/禁放标识、充满/放空状态，动态调整柜子的比例，-->旨在，快充满放空时，拉重合从机SOC曲线，避免长时间运行后出现从机之间SOC偏差较大的问题
#if 1
        for (int i = 0 ; i < var->cabinet_info.num; i++){ // ~~动态scale计算，在快"充满、放空"时，动态计算功率配比，预计在5~6min内可拉重合从机SOC曲线"~~
            cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];
            if (pcs_exp_power > 0){ // 放电
                if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_dischar == 0 && cabinet_inside->cab_data.battery_sta != STATE_EMPTY) {
                    cabinet_inside->cab_ctrl.scale = cabinet_inside->cab_ctrl.pcs_discharge_max_set/pcs_discharge_max_set;
                }
                else{
                    cabinet_inside->cab_ctrl.scale = 0;
                }
            }
            else if (pcs_exp_power < 0){
                if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_char == 0 && cabinet_inside->cab_data.battery_sta != STATE_FULL) {
                    cabinet_inside->cab_ctrl.scale = cabinet_inside->cab_ctrl.pcs_charge_max_set/pcs_charge_max_set;
                }
                else{
                    cabinet_inside->cab_ctrl.scale = 0;
                }
            }
        }
#endif
        for (int i = 0 ; i < var->cabinet_info.num; i++){
            cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];
            if (pcs_exp_power > 0){ // 放电
                if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_dischar == 0 && cabinet_inside->cab_data.battery_sta != STATE_EMPTY) {
                    atomic_store(&var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, pcs_exp_power*var->cabinet_info.cabinet_inside[i]->cab_ctrl.scale);
                    LIMIT_RANGE(var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, 0, var->cabinet_info.cabinet_inside[i]->cab_ctrl.discharge_max_cfg); // 
                }
                else{
                    atomic_store(&var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, 0);
                }
                micro_ac_log(LOG_NOTICE, AC_ID_0023, cabinet_inside->no, IS_KEY, "放电: Cab no: %s, 在线状态：%d, 是否可用: %d(0: 可用 1: 异常), 禁放标识: %d, 动态比例: %f 设置期望功率: %lf ", cabinet_inside->no, cabinet_inside->cab_data.on_line, cabinet_inside->cab_data.en, cabinet_inside->cab_data.prohibited_dischar, var->cabinet_info.cabinet_inside[i]->cab_ctrl.scale, var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power);
            }
            else if (pcs_exp_power < 0){
                if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_data.prohibited_char == 0 && cabinet_inside->cab_data.battery_sta != STATE_FULL) {
                    atomic_store(&var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, pcs_exp_power*var->cabinet_info.cabinet_inside[i]->cab_ctrl.scale);
                    LIMIT_RANGE(var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, var->cabinet_info.cabinet_inside[i]->cab_ctrl.charge_max_cfg, 0); //
                }
                else{
                    atomic_store(&var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power, 0);
                }
                micro_ac_log(LOG_NOTICE, AC_ID_0023, cabinet_inside->no, IS_KEY, "充电: Cab no: %s, 在线状态：%d, 是否可用: %d(0: 可用 1: 异常), 禁充标识: %d, 动态比例: %f 设置期望功率: %lf ", cabinet_inside->no, cabinet_inside->cab_data.on_line, cabinet_inside->cab_data.en, cabinet_inside->cab_data.prohibited_char, var->cabinet_info.cabinet_inside[i]->cab_ctrl.scale, var->cabinet_info.cabinet_inside[i]->cab_ctrl.pcs_exp_power);
            }
        }

        // 分相功率分配：当phase_reflux == 1时，按各柜scale比例分配各相功率
        if (microgrid_ctrl.phase_reflux == 1) {
            double total_phase_power[PHASE_MAX] = {0};
            for (int phase = 0; phase < PHASE_MAX; phase++) {
                total_phase_power[phase] = microgrid_ctrl.pcs_exp_phasepower[phase];
            }
            micro_ac_log(LOG_INFO, AC_ID_0008,NULL,IS_KEY, "分相模式: A相功率: %lf, B相功率: %lf, C相功率: %lf", 
                total_phase_power[PHASE_A], total_phase_power[PHASE_B], total_phase_power[PHASE_C]);
            
            for (int i = 0; i < var->cabinet_info.num; i++) {
                cabinet_inside_t *cabinet_inside = var->cabinet_info.cabinet_inside[i];
                for (int phase = 0; phase < PHASE_MAX; phase++) {
                    if (cabinet_inside->cab_data.on_line == 1 && cabinet_inside->cab_data.en == 0 && cabinet_inside->cab_ctrl.scale > 0) {
                        cabinet_inside->cab_ctrl.pcs_exp_phasepower[phase] = total_phase_power[phase] * cabinet_inside->cab_ctrl.scale;
                    } else {
                        cabinet_inside->cab_ctrl.pcs_exp_phasepower[phase] = 0;
                    }
                }
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL,IS_KEY, "分相模式: Cab no: %s, 动态比例: %f, A相: %lf, B相: %lf, C相: %lf",
                    cabinet_inside->no, cabinet_inside->cab_ctrl.scale,
                    cabinet_inside->cab_ctrl.pcs_exp_phasepower[PHASE_A],
                    cabinet_inside->cab_ctrl.pcs_exp_phasepower[PHASE_B],
                    cabinet_inside->cab_ctrl.pcs_exp_phasepower[PHASE_C]);
            }
        }
    }   
}

static void ac_set_power(void)
{
    dev_info_all_t *var = get_dev_info_all_var();
    cal_and_set_pv_power(var);
    cal_scale_and_set_lc_power(var);
}

static void power_limit(double *pcs_power, double *_ptp, int dirction, STRATAGY_TYPE func, int plan_statu){
    
    if (dirction == CHARGE_DIRECTION){
        if (*pcs_power > 0) *pcs_power = 0; 
        *pcs_power = (*pcs_power < microgrid_ctrl.chargeMaxPower) ? microgrid_ctrl.chargeMaxPower : *pcs_power;
    }  
    if (dirction == DISCHARGE_DIRECTION){
        if (*pcs_power < 0) *pcs_power = 0;
        *pcs_power = (*pcs_power > microgrid_ctrl.dischargeMaxPower) ? microgrid_ctrl.dischargeMaxPower : *pcs_power;
        if (func == STRATAGY_TYPE_PERIOD_CTRL && plan_statu == DISCHARGE_DIRECTION){
            *pcs_power = *pcs_power > microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power : *pcs_power; // 削峰填谷，峰电-->使用计划放电功率，作为放电上限
        }
    }    

#if 1 // PV
    if (*_ptp < 0) *_ptp = 0;
    *_ptp = *_ptp > microgrid_ctrl.pvMax ? microgrid_ctrl.pvMax : *_ptp;
#endif
}

static void cal_support_power(double *charge_limit, double *discharge_limit, STRATAGY_TYPE func, int plan_statu)
{
    *discharge_limit = microgrid_ctrl.discharge_max_set > microgrid_ctrl.dischargeMaxPower ? microgrid_ctrl.dischargeMaxPower : microgrid_ctrl.discharge_max_set;
    if (func == STRATAGY_TYPE_PERIOD_CTRL && plan_statu == DISCHARGE_DIRECTION){
        *discharge_limit = *discharge_limit > microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power : *discharge_limit;
    }

    *charge_limit = microgrid_ctrl.charge_max_set < microgrid_ctrl.chargeMaxPower ? microgrid_ctrl.chargeMaxPower: microgrid_ctrl.charge_max_set;
    if (func == STRATAGY_TYPE_PERIOD_CTRL && plan_statu == CHARGE_DIRECTION){
        *charge_limit = *charge_limit < microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power : *charge_limit;
    }
}

// pcs_exp_power 负充正放  算法周期，不建议低于500ms
static int ac_cal_peak_pv_power(double *pcs_exp_power, double *pv_target_power, int EnReflux, int EnTraceLoad, int en_ac_d2c, STRATAGY_TYPE func)
{
    int dirction = 0;
    double _ptp = 0, _pcs_power = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    double grid_power = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
    double charge_limit = 0, discharge_limit = 0;

    cal_support_power(&charge_limit, &discharge_limit, func, DISCHARGE_DIRECTION);
    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "当前 储能最大可吸收功率: %lf, 最大支持放电功率: %lf ", fabs(charge_limit), discharge_limit);

    double min_output = microgrid_data.night_flag == 1 ? 0 : (0 - microgrid_ctrl.anti_reflux);
    if (EnReflux || EnTraceLoad){
        double exp_power = 0;

        if (EnTraceLoad && microgrid_ctrl.EnPhaseCtrl == 0){
            double grid = grid_power - (grid_power + microgrid_data.pcs_power + microgrid_data.pv_power) * microgrid_ctrl.TraceLoad;

            exp_power = antiReflux(
                grid, 
                1,  
                1, 
                microgrid_ctrl.pvMax + discharge_limit, 
                0,                                         
                microgrid_data.pcs_power + microgrid_data.pv_power,
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "负荷跟踪, 负载期望功率: %lf ", exp_power);
        }
        else{
            if (microgrid_ctrl.EnPhaseCtrl == 0){
                exp_power = antiReflux(
                    grid_power,
                    microgrid_ctrl.anti_reflux,
                    1,
                    microgrid_ctrl.pvMax + discharge_limit,
                    min_output,                                          // 负载小于防逆流下限时，可返回负值，表示希望PCS多充一点电，保证防逆流余量
                    microgrid_data.pcs_power + microgrid_data.pv_power,  /* 逆流转充，储能充电功率一定低于光伏 算法自适应，*/
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "在保证防逆流前提下, 负载期望功率: %lf ", exp_power);
            }
            else{
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "单相防逆流模式, A相: %lf B相: %lf C相: %lf",
                    microgrid_ctrl.pcs_exp_phasepower[PHASE_A], microgrid_ctrl.pcs_exp_phasepower[PHASE_B], microgrid_ctrl.pcs_exp_phasepower[PHASE_C]);
                // A相
                {
                    double grid_a = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.AphaseActivePower;
                    if (EnTraceLoad){
                        double grid = grid_a - (grid_a + microgrid_data.PhasePower[PHASE_A]) * microgrid_ctrl.TraceLoad;
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_A] = antiReflux_A(grid, 1, 1, microgrid_ctrl.pvMax + discharge_limit, 0, microgrid_data.PhasePower[PHASE_A], 0);
                    }
                    else{
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_A] = antiReflux_A(grid_a, microgrid_ctrl.anti_reflux, 1, microgrid_ctrl.pvMax + discharge_limit, min_output, microgrid_data.PhasePower[PHASE_A], 0);
                    }
                    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "A相 期望功率: %lf", microgrid_ctrl.pcs_exp_phasepower[PHASE_A]);
                }
                // B相
                {
                    double grid_b = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.BphaseActivePower;
                    if (EnTraceLoad){
                        double grid = grid_b - (grid_b + microgrid_data.PhasePower[PHASE_B]) * microgrid_ctrl.TraceLoad;
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_B] = antiReflux_B(grid, 1, 1, microgrid_ctrl.pvMax + discharge_limit, 0, microgrid_data.PhasePower[PHASE_B], 0);
                    }
                    else{
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_B] = antiReflux_B(grid_b, microgrid_ctrl.anti_reflux, 1, microgrid_ctrl.pvMax + discharge_limit, min_output, microgrid_data.PhasePower[PHASE_B], 0);
                    }
                    micro_ac_log(LOG_INFO, AC_ID_0008, NULL,IS_KEY, "B相 期望功率: %lf", microgrid_ctrl.pcs_exp_phasepower[PHASE_B]);
                }
                // C相
                {
                    double grid_c = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.CphaseActivePower;
                    if (EnTraceLoad){
                        double grid = grid_c - (grid_c + microgrid_data.PhasePower[PHASE_C]) * microgrid_ctrl.TraceLoad;
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_C] = antiReflux_C(grid, 1, 1, microgrid_ctrl.pvMax + discharge_limit, 0, microgrid_data.PhasePower[PHASE_C], 0);
                    }
                    else{
                        microgrid_ctrl.pcs_exp_phasepower[PHASE_C] = antiReflux_C(grid_c, microgrid_ctrl.anti_reflux, 1, microgrid_ctrl.pvMax + discharge_limit, min_output, microgrid_data.PhasePower[PHASE_C], 0);
                    }
                    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "C相 期望功率: %lf", microgrid_ctrl.pcs_exp_phasepower[PHASE_C]);
                }
                exp_power = microgrid_ctrl.pcs_exp_phasepower[PHASE_A] + microgrid_ctrl.pcs_exp_phasepower[PHASE_B] + microgrid_ctrl.pcs_exp_phasepower[PHASE_C];
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "单相防逆流, 合计期望功率: %lf", exp_power);
            } 
        }

        //exp_power = exp_power < 0 ? 0 : exp_power;//
        if (en_ac_d2c){ //>>开启逆流转充，默认关闭
            _ptp = exp_power + fabs(charge_limit); // 在储能充电过程中，'预干预'最大充电功率限制，使调整更加平滑，防止储能充满出现"断崖式"曲线，光伏来不及调节时导致逆流
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "开启逆流转充, 光伏目标功率(%lf) = 负载期望功率(%lf) + 储能最大可吸收功率(%lf) ", _ptp, exp_power, fabs(charge_limit));
        }
        else{
            _ptp = exp_power;
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "禁止逆流转充, 光伏目标功率(%lf) = 负载期望功率(%lf) ", _ptp, exp_power);
        }

        double tmp = 0 - (microgrid_data.pv_power - exp_power);
        if (tmp < 0 && en_ac_d2c == 1){
            _pcs_power = tmp;  // ~~ PCS充电功率，被动
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "启动反流保护，储能充电~~, _pcs_power: %lf", _pcs_power); // 1. 若储能没有满功率充电，在光伏突升、负载突降时，储能可快速消纳逆流部分功率 2. 若储能已满功率充电，只能等待PV慢慢降了
            dirction = CHARGE_DIRECTION;
        }
        else if (tmp > 1){
            if (microgrid_ctrl.discharge_max_set == 0){ 
                _pcs_power = 0;
            }
            else{
                _pcs_power = tmp;
                micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "1. 在光伏上升过程中/ 2.光线不好，光伏不够 -->电池补电~~, _pcs_power: %lf", _pcs_power);
                dirction = DISCHARGE_DIRECTION;
            }
        }               
        else
            _pcs_power = 0;
    }
    else{
        if(func == STRATAGY_TYPE_PERIOD_CTRL && 0 == microgrid_cfg.en_photovoltaic){  
            _pcs_power = microgrid_ctrl.plan_set_power;
        }
        else{
            _ptp = microgrid_ctrl.pvMax; // 1.可控光伏，直接设置最大 2.不控光伏

            if (func == STRATAGY_TYPE_PERIOD_CTRL && en_ac_d2c == 0){
                micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "削峰填谷模式且没有使能逆流转充!!!，意味着光伏上网更划算，光伏和储能的电一起上网");
                _pcs_power = microgrid_ctrl.plan_set_power;
            }
            else{
                // 算法忽略光伏/其他电源（柴发）的存在，即：1.电网大于0则增加储能放电功率即可 2.逆流就降储能放电功率，直至PCS降到0功率，若还逆流就充电，储能用不完的电可同时上网
                double tmp_min_out = 0;
                if (func == STRATAGY_TYPE_PV_STORAGE || (func == STRATAGY_TYPE_PERIOD_CTRL && en_ac_d2c == 1))
                    tmp_min_out = charge_limit;
                double exp_power = 0.0f;
                if (microgrid_ctrl.choose_func == STRATAGY_TYPE_TOU && microgrid_ctrl.current_tou_info) 
                {
                    exp_power = antiReflux(
                    grid_power + microgrid_ctrl.current_tou_info->SurplusToGrid, 
                    0, 
                    1, 
                    discharge_limit + microgrid_ctrl.pvMax, 
                    tmp_min_out, 
                    microgrid_data.pcs_power + microgrid_data.pv_power, 
                    0);
                    _ptp = exp_power + (-charge_limit);
                    if (microgrid_ctrl.current_tou_info->strategy == 1) //TOU的上网优先模式 
                    {
                        _pcs_power = 0 - (microgrid_data.pv_power - exp_power);
                    }
                    else if(microgrid_ctrl.current_tou_info->strategy == 0)//TOU的自发自用模式
                    {
                        _pcs_power = 0 - (microgrid_data.pv_power - exp_power + microgrid_ctrl.current_tou_info->SurplusToGrid); //多的给pcs
                    }
                    
                }
                else if(microgrid_ctrl.choose_func == STRATAGY_TYPE_SURPLUS2GRID)//上网优先
                {
                    exp_power = antiReflux(
                    grid_power + microgrid_ctrl.SurplusPower, 
                    0, 
                    1, 
                    discharge_limit + microgrid_ctrl.pvMax,
                    tmp_min_out, 
                    microgrid_data.pcs_power + microgrid_data.pv_power, 
                    0);
                    _ptp = exp_power + (-charge_limit);
                    _pcs_power = 0 - (microgrid_data.pv_power - exp_power);
                }
                else{
                    exp_power = antiReflux(
                    grid_power, 
                    microgrid_ctrl.anti_reflux, 
                    1, 
                    discharge_limit, 
                    tmp_min_out, 
                    microgrid_data.pcs_power, 
                    0);

                    if (exp_power == 0){
                    _pcs_power = 0;
                    }
                    else if (exp_power < 0){
                        _pcs_power = exp_power;
                        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "光伏/其他电源 多余, 电池充电, 储能用不完的电就直接上网了...,  _pcs_power: %lf", _pcs_power);
                        dirction = CHARGE_DIRECTION;
                    }
                    else{
                        if (microgrid_ctrl.discharge_max_set == 0){ 
                            _pcs_power = 0;
                        }
                        else{
                            _pcs_power = exp_power;
                            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "光伏/其他电源 不够, -->电池补电, _pcs_power: %lf", _pcs_power);
                            dirction = DISCHARGE_DIRECTION;
                        }
                    }
                }
            }
        }
    }

    power_limit(&_pcs_power, &_ptp, dirction, func, DISCHARGE_DIRECTION);
    
    *pcs_exp_power = _pcs_power; *pv_target_power = _ptp;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "pcs_exp_power: %lf, pv_target_power: %lf", *pcs_exp_power, *pv_target_power);
    return dirction;
}

static void ac_start_PeakElec_process(int en_ac_d2c, STRATAGY_TYPE func)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率
    
    if (func == STRATAGY_TYPE_PERIOD_CTRL){
        micro_ac_log(LOG_INFO, AC_ID_0009, "mode", IS_KEY, "削峰填谷，放电时间段(尖电)");
    }
    else if(func == STRATAGY_TYPE_PV_STORAGE){
        micro_ac_log(LOG_INFO, AC_ID_0009, "mode", IS_KEY, "光伏消纳");
    }
    ac_cal_peak_pv_power(&pcs_exp_power, &pv_target_power, microgrid_ctrl.en_anti_reflux, microgrid_ctrl.EnTraceLoad, en_ac_d2c, func);

    adjust_to_target(pv_target_power, pcs_exp_power);
    
    ac_set_power();
}
static int ac_cal_vall_pv_power_tou(double *pcs_exp_power, double *pv_target_power, int EnProtectTransf, int EnReflux, int EnTraceLoad, int en_ac_c2d, STRATAGY_TYPE func)
{
    int dirction = 0;
    double _ptp = 0, _pcs_power = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    double grid_power = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
    double charge_limit = 0, discharge_limit = 0;

    cal_support_power(&charge_limit, &discharge_limit, func, CHARGE_DIRECTION);
    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "当前 储能最大可吸收功率: %lf, 最大支持放电功率: %lf", fabs(charge_limit), discharge_limit);

    double power_HV = 0, power_LV = 0;

    if (EnProtectTransf == 0 && microgrid_ctrl.EnProtectTrasLV == 0){
        _pcs_power = charge_limit;
        dirction = CHARGE_DIRECTION;
    }
    else{
        if (EnProtectTransf && microgrid_ctrl.EnProtectTrasLV){ // 若高低压侧都开启，不允许超容放电（无此场景）
            en_ac_c2d = 0;
            discharge_limit = 0;
        }

        if (EnProtectTransf){
            if (EnProtectTransf == 1){

                double grid_appower = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.appr_power;

                double _Pmlmax = (microgrid_ctrl.Pmlmax / 1.0) * ((double)microgrid_ctrl.K1 / 100.0);
                power_HV = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_appower, 
                    microgrid_ctrl.Pmlmax,  
                    1, 
                    discharge_limit, 
                    charge_limit, 
                    microgrid_data.pcs_power, 
                    _Pmlmax,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "高压侧变压器保护， power_HV: %lf", power_HV);
            }  
            else if (EnProtectTransf == 2){ // 需量保护
                double max_demand = microgrid_ctrl.MaxDemand;    // 需量门限       
                max_demand = microgrid_ctrl.Pmlmax  < max_demand ? microgrid_ctrl.Pmlmax : max_demand;
                        
                double _max_demand = max_demand - microgrid_ctrl.PmlmaxDiff;
                _max_demand = _max_demand > 0 ? _max_demand : 0;

                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "最大需量: %lf， 需量回差: %lf", max_demand, microgrid_ctrl.PmlmaxDiff);
                power_HV = xl_antiReflux(  // 需量保护，在保证不超需量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_power, 
                    max_demand,  
                    1, 
                    discharge_limit, 
                    charge_limit, 
                    microgrid_data.pcs_power, 
                    _max_demand,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "需量保护， power_HV: %lf", power_HV);
            }
        }

        if (microgrid_ctrl.EnProtectTrasLV){ // 低压侧变压器保护

            double lv_grid_appower = _dev_info_all->meter_grid_lv.meter_grid_param[0].info.meter_grid_data.appr_power;
            
            double _Pmlmax = (microgrid_ctrl.PLVmlmax / 1.0) * ((double)microgrid_ctrl.k4 / 100.0);
            power_LV = xl_LV_antiReflux(lv_grid_appower, 
                (double)microgrid_ctrl.PLVmlmax, 
                1, 
                discharge_limit, 
                charge_limit, 
                microgrid_data.pcs_power,
                _Pmlmax, 
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "低压侧变压器保护， power_LV: %lf", power_LV);
        }
      
        double _exp_power = 0;
        if(EnProtectTransf)
        {
            if(microgrid_ctrl.EnProtectTrasLV){
                if(power_LV < power_HV){
                    _exp_power = power_HV;
                }
                else{
                    _exp_power = power_LV;
                }
            }
            else {
                _exp_power = power_HV;
            }
        }
        else {
            if(microgrid_ctrl.EnProtectTrasLV)
                _exp_power = power_LV;
        }

        if (en_ac_c2d == 0){
            _exp_power = _exp_power > 0 ? 0 : _exp_power;//
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "禁用超容转放, 在保证不超过变压器容量的前提下, 储能期望充电功率 _exp_power: %lf", _exp_power);
        }
        else{
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "启用超容转放, 储能期望功率 _exp_power: %lf", _exp_power);
        }
        if (func == STRATAGY_TYPE_PERIOD_CTRL){
            _exp_power = _exp_power < microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power : _exp_power; // 削峰填谷，谷电-->使用计划充电功率，作为充电上限
        }
        _pcs_power = _exp_power;
        dirction = _exp_power > 0 ? DISCHARGE_DIRECTION : CHARGE_DIRECTION;
    }

    if (EnReflux || EnTraceLoad){ // 若高低压侧都开启，只需高压侧做 负荷跟踪/防逆流（低压侧看成导线）
        double exp_power = 0;
        double pv_exp_power = 0;
        if (EnTraceLoad){
            double grid = grid_power - (grid_power + microgrid_data.pcs_power + microgrid_data.pv_power) * microgrid_ctrl.TraceLoad;

            exp_power = antiReflux(
                grid, 
                1,  
                1, 
                microgrid_ctrl.pvMax - charge_limit, 
                0,                         
                microgrid_data.pcs_power + microgrid_data.pv_power,
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "负载跟踪, 负载期望功率 exp_power: %lf", exp_power);
        }
        else{
            pv_exp_power = antiReflux(
                grid_power, 
                microgrid_ctrl.anti_reflux,  
                1, 
                microgrid_ctrl.pvMax - charge_limit, 
                -microgrid_ctrl.anti_reflux,                         // 负载小于防逆流下限时，可返回负值，表示希望光伏少发一点电，保证防逆流余量
                microgrid_data.pcs_power + microgrid_data.pv_power,  /* 如果功率低于0 说明电网在补电 算法自适应，刚好减掉电网上补充的部分，算出实际负载需求 */
                0);
        }
        
        micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "在保证防逆流前提下, 光伏期望功率 exp_power: %lf", pv_exp_power);
        power_limit(&_pcs_power, &_ptp, dirction, func, CHARGE_DIRECTION);
        _ptp = pv_exp_power - _pcs_power + microgrid_data.pcs_power;//光伏设置为防逆流期望加pcs期望-pcs实际的
        if (!microgrid_ctrl.current_tou_info->ChargeGrid) //不允许电网补电则使用光伏的功率
        {
            _pcs_power = -microgrid_data.pv_power > _pcs_power? -microgrid_data.pv_power : _pcs_power;
        }
    }      
    else{
        double pv_exp_power = 0;
        power_limit(&_pcs_power, &_ptp, dirction, func, CHARGE_DIRECTION);
        pv_exp_power = antiReflux(
            grid_power + microgrid_ctrl.current_tou_info->SurplusToGrid, 
            0,  
            1, 
            microgrid_ctrl.pvMax, 
            0,     // 负载小于防逆流下限时，可返回负值，表示希望光伏少发一点电，保证防逆流余量
            microgrid_data.pcs_power + microgrid_data.pv_power,  /* 如果功率低于0 说明电网在补电 算法自适应，刚好减掉电网上补充的部分，算出实际负载需求 */
            0);
        micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "在保证防逆流前提下, 光伏期望功率 exp_power: %lf", pv_exp_power);
        _ptp = pv_exp_power - _pcs_power;
        power_limit(&_pcs_power, &_ptp, dirction, func, CHARGE_DIRECTION);
        
        if (!microgrid_ctrl.current_tou_info->ChargeGrid) //不允许电网补电则使用光伏的功率
        {
            _pcs_power = -microgrid_data.pv_power > _pcs_power? -microgrid_data.pv_power : _pcs_power;
        }
    }

    power_limit(&_pcs_power, &_ptp, dirction, func, CHARGE_DIRECTION);
    *pcs_exp_power = _pcs_power; *pv_target_power = _ptp;
    micro_ac_log(LOG_NOTICE, INIT_ID_0000, NULL, NOT_KEY, "pcs_exp_power: %lf, pv_target_power: %lf", *pcs_exp_power, *pv_target_power);
    return dirction;
}

static int ac_cal_vall_pv_power(double *pcs_exp_power, double *pv_target_power, int EnProtectTransf, int EnReflux, int EnTraceLoad, int en_ac_c2d, STRATAGY_TYPE func)
{
    int dirction = 0;
    double _ptp = 0, _pcs_power = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    double grid_power = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
    double charge_limit = 0, discharge_limit = 0;

    cal_support_power(&charge_limit, &discharge_limit, func, CHARGE_DIRECTION);
    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "当前 储能最大可吸收功率: %lf, 最大支持放电功率: %lf", fabs(charge_limit), discharge_limit);

    double power_HV = 0, power_LV = 0;

    if (EnProtectTransf == 0 && microgrid_ctrl.EnProtectTrasLV == 0){
        _pcs_power = charge_limit;
        dirction = CHARGE_DIRECTION;
    }
    else{
        if (EnProtectTransf && microgrid_ctrl.EnProtectTrasLV){ // 若高低压侧都开启，不允许超容放电（无此场景）
            en_ac_c2d = 0;
            discharge_limit = 0;
        }

        if (EnProtectTransf){
            if (EnProtectTransf == 1){

                double grid_appower = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.appr_power;

                double _Pmlmax = (microgrid_ctrl.Pmlmax / 1.0) * ((double)microgrid_ctrl.K1 / 100.0);
                power_HV = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_appower, 
                    microgrid_ctrl.Pmlmax,  
                    1, 
                    discharge_limit, 
                    charge_limit, 
                    microgrid_data.pcs_power, 
                    _Pmlmax,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "高压侧变压器保护， power_HV: %lf", power_HV);
            }  
            else if (EnProtectTransf == 2){ // 需量保护
                double max_demand = microgrid_ctrl.MaxDemand;    // 需量门限       
                max_demand = microgrid_ctrl.Pmlmax  < max_demand ? microgrid_ctrl.Pmlmax : max_demand;
                        
                double _max_demand = max_demand - microgrid_ctrl.PmlmaxDiff;
                _max_demand = _max_demand > 0 ? _max_demand : 0;

                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "最大需量: %lf， 需量回差: %lf", max_demand, microgrid_ctrl.PmlmaxDiff);
                power_HV = xl_antiReflux(  // 需量保护，在保证不超需量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_power, 
                    max_demand,  
                    1, 
                    discharge_limit, 
                    charge_limit, 
                    microgrid_data.pcs_power, 
                    _max_demand,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "需量保护， power_HV: %lf", power_HV);
            }
        }

        if (microgrid_ctrl.EnProtectTrasLV){ // 低压侧变压器保护

            double lv_grid_appower = _dev_info_all->meter_grid_lv.meter_grid_param[0].info.meter_grid_data.appr_power;
            
            double _Pmlmax = (microgrid_ctrl.PLVmlmax / 1.0) * ((double)microgrid_ctrl.k4 / 100.0);
            power_LV = xl_LV_antiReflux(lv_grid_appower, 
                (double)microgrid_ctrl.PLVmlmax, 
                1, 
                discharge_limit, 
                charge_limit, 
                microgrid_data.pcs_power,
                _Pmlmax, 
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "低压侧变压器保护， power_LV: %lf", power_LV);
        }
      
        double _exp_power = 0;
        if(EnProtectTransf)
        {
            if(microgrid_ctrl.EnProtectTrasLV){
                if(power_LV < power_HV){
                    _exp_power = power_HV;
                }
                else{
                    _exp_power = power_LV;
                }
            }
            else {
                _exp_power = power_HV;
            }
        }
        else {
            if(microgrid_ctrl.EnProtectTrasLV)
                _exp_power = power_LV;
        }

        if (en_ac_c2d == 0){
            _exp_power = _exp_power > 0 ? 0 : _exp_power;//
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "禁用超容转放, 在保证不超过变压器容量的前提下, 储能期望充电功率 _exp_power: %lf", _exp_power);
        }
        else{
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "启用超容转放, 储能期望功率 _exp_power: %lf", _exp_power);
        }
        if (func == STRATAGY_TYPE_PERIOD_CTRL){
            _exp_power = _exp_power < microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power : _exp_power; // 削峰填谷，谷电-->使用计划充电功率，作为充电上限
        }
        _pcs_power = _exp_power;
        dirction = _exp_power > 0 ? DISCHARGE_DIRECTION : CHARGE_DIRECTION;
    }

    if (EnReflux || EnTraceLoad){ // 若高低压侧都开启，只需高压侧做 负荷跟踪/防逆流（低压侧看成导线）
        double exp_power = 0;

        if (EnTraceLoad){
            double grid = grid_power - (grid_power + microgrid_data.pcs_power + microgrid_data.pv_power) * microgrid_ctrl.TraceLoad;

            exp_power = antiReflux(
                grid, 
                1,  
                1, 
                microgrid_ctrl.pvMax + discharge_limit, 
                0,                         
                microgrid_data.pcs_power + microgrid_data.pv_power,
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "负载跟踪, 负载期望功率 exp_power: %lf", exp_power);
        }
        else{
            exp_power = antiReflux(
                grid_power, 
                microgrid_ctrl.anti_reflux,  
                1, 
                microgrid_ctrl.pvMax + discharge_limit, 
                -microgrid_ctrl.anti_reflux,                         // 负载小于防逆流下限时，可返回负值，表示希望光伏少发一点电，保证防逆流余量
                microgrid_data.pcs_power + microgrid_data.pv_power,  /* 如果功率低于0 说明电网在补电 算法自适应，刚好减掉电网上补充的部分，算出实际负载需求 */
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "在保证防逆流前提下, 负载期望功率 exp_power: %lf", exp_power);
        }

        if (microgrid_data.pcs_power > 0){
            _ptp = microgrid_ctrl.pvMax;
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "储能放电, 光伏直接设置最大(%lf)", _ptp);
        }
        else{
            _ptp = exp_power + fabs(microgrid_data.pcs_power);
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "储能充电, 光伏目标功率(%lf) = 负载期望功率(%lf) + 储能当前充电功率(%lf)", _ptp, exp_power, fabs(microgrid_data.pcs_power));
        }
    }      
    else{
            _ptp = microgrid_ctrl.pvMax;
    }

    power_limit(&_pcs_power, &_ptp, dirction, func, CHARGE_DIRECTION);
    *pcs_exp_power = _pcs_power; *pv_target_power = _ptp;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "pcs_exp_power: %lf, pv_target_power: %lf", *pcs_exp_power, *pv_target_power);
    return dirction;
}

static void ac_start_VallElec_process(int en_ac_c2d, STRATAGY_TYPE func)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率

    if (func == STRATAGY_TYPE_PERIOD_CTRL){
        micro_ac_log(LOG_INFO, AC_ID_0009, "mode", IS_KEY, "削峰填谷，充电时间段(谷电)");
    }
    else if(func == STRATAGY_TYPE_STANDBY){
        micro_ac_log(LOG_INFO, AC_ID_0009, "mode", IS_KEY, "应急备电");
    }
 
    if (microgrid_ctrl.choose_func == STRATAGY_TYPE_TOU && microgrid_ctrl.current_tou_info)
    {
        ac_cal_vall_pv_power_tou(&pcs_exp_power, &pv_target_power, microgrid_ctrl.EnProtectTransf, microgrid_ctrl.en_anti_reflux, microgrid_ctrl.EnTraceLoad, en_ac_c2d, func);
    }
    else
    {
        ac_cal_vall_pv_power(&pcs_exp_power, &pv_target_power, microgrid_ctrl.EnProtectTransf, microgrid_ctrl.en_anti_reflux, microgrid_ctrl.EnTraceLoad, en_ac_c2d, func);
    }
    
    adjust_to_target(pv_target_power, pcs_exp_power);
    
    ac_set_power();
}

// pcs_exp_power 负充正放，平电禁止储能放电
static int ac_cal_falt_pv_power(double *pcs_exp_power, double *pv_target_power, int EnProtectTransf, int EnReflux, int EnTraceLoad, int en_ac_c2d, STRATAGY_TYPE func)
{
    int dirction = 0;
    double _ptp = 0, _pcs_power = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    double grid_power = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
    double charge_limit = 0, discharge_limit = 0;

    cal_support_power(&charge_limit, &discharge_limit, func, ENERGY_DEFAULT);
    micro_ac_log(LOG_INFO, AC_ID_0032, NULL, NOT_KEY, "当前 储能最大可吸收功率, charge_limit: %lf", fabs(charge_limit));

    double power_HV = 0, power_LV = 0;

    if (EnProtectTransf == 0 && microgrid_ctrl.EnProtectTrasLV == 0){
        _pcs_power = 0;
    }
    else{
        if (EnProtectTransf && microgrid_ctrl.EnProtectTrasLV){ // 若高低压侧都开启，不允许超容放电（无此场景）
            en_ac_c2d = 0;
            discharge_limit = 0;
        }

        if (EnProtectTransf){
            if (EnProtectTransf == 1){

                double grid_appower = _dev_info_all->meter_grid.meter_grid_param[0].info.meter_grid_data.appr_power;

                double _Pmlmax = (microgrid_ctrl.Pmlmax / 1.0) * ((double)microgrid_ctrl.K1 / 100.0);
                power_HV = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_appower, 
                    microgrid_ctrl.Pmlmax,  
                    1, 
                    discharge_limit, 
                    0, 
                    microgrid_data.pcs_power, 
                    _Pmlmax,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "高压侧变压器保护， power_HV: %lf", power_HV);
            }  
            else if (EnProtectTransf == 2){ // 需量保护
                double max_demand = microgrid_ctrl.MaxDemand;    // 需量门限       
                max_demand = microgrid_ctrl.Pmlmax  < max_demand ? microgrid_ctrl.Pmlmax : max_demand;
                        
                double _max_demand = max_demand - microgrid_ctrl.PmlmaxDiff;
                _max_demand = _max_demand > 0 ? _max_demand : 0;

                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "最大需量: %lf， 需量回差: %lf", max_demand, microgrid_ctrl.PmlmaxDiff);
                power_HV = xl_antiReflux(  // 需量保护，在保证不超需量的前提下，尽可能靠近充电功率上限，PCS充电功率，主动
                    grid_power, 
                    max_demand,  
                    1, 
                    discharge_limit, 
                    0, 
                    microgrid_data.pcs_power, 
                    _max_demand,
                    0);
                micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "需量保护， power_HV: %lf", power_HV);
            }
        }

        if (microgrid_ctrl.EnProtectTrasLV){ // 低压侧变压器保护

            double lv_grid_appower = _dev_info_all->meter_grid_lv.meter_grid_param[0].info.meter_grid_data.appr_power;
            
            double _Pmlmax = (microgrid_ctrl.PLVmlmax / 1.0) * ((double)microgrid_ctrl.k4 / 100.0);
            power_LV = xl_LV_antiReflux(lv_grid_appower, 
                (double)microgrid_ctrl.PLVmlmax, 
                1, 
                discharge_limit, 
                0, 
                microgrid_data.pcs_power,
                _Pmlmax, 
                0);
            micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "低压侧变压器保护， power_LV: %lf", power_LV);
        }
      
        double _exp_power = 0;
        if(EnProtectTransf)
        {
            if(microgrid_ctrl.EnProtectTrasLV){
                if(power_LV < power_HV){
                    _exp_power = power_HV;
                }
                else{
                    _exp_power = power_LV;
                }
            }
            else {
                _exp_power = power_HV;
            }
        }
        else {
            if(microgrid_ctrl.EnProtectTrasLV)
                _exp_power = power_LV;
        }

        if (en_ac_c2d == 0){
            _exp_power = _exp_power > 0 ? 0 : _exp_power;//
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "禁用超容转放, 在保证不超过变压器容量的前提下, 储能期望充电功率 _exp_power: %lf", _exp_power);
        }
        else{
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "启用超容转放, 储能期望功率 _exp_power: %lf", _exp_power);
        }
        _pcs_power = _exp_power;
        dirction = _exp_power > 0 ? DISCHARGE_DIRECTION : CHARGE_DIRECTION;

        if (_pcs_power > 0){
            _ptp = microgrid_ctrl.pvMax;
            micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "储能放电, 光伏直接设置最大(%lf)", _ptp);
        }
    }

    if (_pcs_power == 0){ // 没有超容
        double min_output = microgrid_data.night_flag == 1 ? 0 : (0 - microgrid_ctrl.anti_reflux);
        if (EnReflux || EnTraceLoad){
            if(0 == microgrid_cfg.en_photovoltaic){ // 禁用光伏
                _pcs_power = 0;
            }
            else{
                double exp_power = 0;

                if (EnTraceLoad){
                    double grid = grid_power - (grid_power + microgrid_data.pcs_power + microgrid_data.pv_power) * microgrid_ctrl.TraceLoad;

                    exp_power = antiReflux(
                        grid, 
                        1,  
                        1, 
                        microgrid_ctrl.pvMax + discharge_limit, 
                        0,                         
                        microgrid_data.pcs_power + microgrid_data.pv_power,
                        0);
                    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "负载跟踪, 负载期望功率 exp_power: %lf", exp_power);
                }
                else{
                    exp_power = antiReflux(
                        grid_power, 
                        microgrid_ctrl.anti_reflux,  
                        1, 
                        microgrid_ctrl.pvMax, 
                        min_output,                                         // 负载小于防逆流下限时，可返回负值，表示希望储能多充一点电，保证防逆流余量 
                        microgrid_data.pcs_power + microgrid_data.pv_power, /* 充电，储能充电功率一定低于光伏 算法自适应，*/
                        0);
                    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "在保证防逆流前提下, 负载期望功率 exp_power: %lf", exp_power);
                }
                //exp_power = exp_power < 0 ? 0 : exp_power;// 
                _ptp = exp_power + fabs(charge_limit);  
                micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "光伏目标功率(%lf) = 负载期望功率(%lf) + 储能最大可吸收功率(%lf)", _ptp, exp_power, fabs(charge_limit));

                double tmp = 0 - (microgrid_data.pv_power - exp_power);
                if (tmp < 0){
                    _pcs_power = tmp; // ~~ PCS充电功率，被动
                    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "启动反流保护，储能充电~~, _pcs_power: %lf", _pcs_power); // 1. 若储能没有满功率充电，在光伏突升、负载突降时，储能可快速消纳逆流部分的功率 2. 若储能已满功率充电，只能等待PV慢慢降了
                    dirction = CHARGE_DIRECTION;
                }
                else {
                    _pcs_power = 0;
                    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "1. 在光伏上升过程中/ 2.光线不好，光伏不够 -->电池静置，市电补充~~, _pcs_power: %lf", _pcs_power);
                }
            }             
        }
        else{
            if(0 == microgrid_cfg.en_photovoltaic){
                _pcs_power = 0;
            }
            else{
                _ptp = microgrid_ctrl.pvMax; // 1.可控光伏，直接设置最大 2.不控光伏
                
                // 算法忽略光伏/其他电源（柴发）的存在，即：1.电网大于0则增加储能放电功率即可 2.逆流就降储能放电功率，直至PCS降到0功率，若还逆流就充电，储能用不完的电可同时上网
                double tmp_min_out = charge_limit;
                    
                double exp_power = antiReflux(
                    grid_power, 
                    microgrid_ctrl.anti_reflux,  
                    1, 
                    discharge_limit, 
                    tmp_min_out, 
                    microgrid_data.pcs_power, 
                    0);

                if (exp_power == 0){
                    _pcs_power = 0;
                }
                else if (exp_power < 0){
                    _pcs_power = exp_power;
                    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "光伏/其他电源 多余, 电池充电, 储能用不完的电就直接上网了...,  _pcs_power: %lf", _pcs_power);

                    dirction = CHARGE_DIRECTION;
                }
                else{
                    _pcs_power = 0;
                    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "1. 在光伏上升过程中/ 2.光线不好，光伏不够 -->电池静置，市电补充~~, _pcs_power: %lf", _pcs_power);
                }
            }
        }
    }


    power_limit(&_pcs_power, &_ptp, dirction, func, ENERGY_DEFAULT);

    *pcs_exp_power = _pcs_power;  *pv_target_power = _ptp;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "pcs_exp_power: %lf, pv_target_power: %lf", *pcs_exp_power, *pv_target_power);
    return dirction;
}

static void ac_start_FaltElec_process(int en_ac_c2d, STRATAGY_TYPE func)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率

    micro_ac_log(LOG_NOTICE, AC_ID_0009, "mode", IS_KEY, "削峰填谷，静置时间段(平电)");

    ac_cal_falt_pv_power(&pcs_exp_power, &pv_target_power, microgrid_ctrl.EnProtectTransf, microgrid_ctrl.en_anti_reflux, microgrid_ctrl.EnTraceLoad, en_ac_c2d, func);

    adjust_to_target(pv_target_power, pcs_exp_power);

    ac_set_power();
}

static void unknow_status_standing(void){
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率

    micro_ac_log(LOG_WARNING, AC_ID_0032, NULL, NOT_KEY, "设置PCS，光伏0功率!!!");
    adjust_to_target(pv_target_power, pcs_exp_power);
    ac_set_power();
}

int last_paln_statu = -1;
static void ac_Cutpeak_Fillvalley(void)
{
    /* 削峰填谷策略功能概述：：：：：：
       1. 峰电（放电时间段）：--耗电单元：【负载】  
#if 0
       2. 平电（静置时间段）：--耗电单元：【负载】
            光伏优先给负载供电，不够则市电补充，光伏多余，储能充电（注意：不能拿市电)，若储能充满，限制光伏功率；
       3. 谷电（充电时间段）：--耗电单元：【负载 + 储能】
        unknow_status_standing();
    */
#if 0
    if(0 == microgrid_cfg.en_photovoltaic)   // 光伏失能，返回，设置PCS，光伏0功率
    {
        micro_ac_log(LOG_ERR, AC_ID_0032, NOT_KEY,  "当前AC微网模式，必须使能光伏!!! set_power pcs and pv = 0...");
        unknow_status_standing();
        return;
    }
#endif
// 站在交流母线，系统层次上理解算法参数
// 注意：~~~~~~~~ 不使能光伏时，算法兼容，仍可运行削峰填谷策略，pvMax 需设置0 ~~~~~~~~
    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "当前计划:[%d]  %d:放电 %d:充电 %d:静置", microgrid_ctrl.plan_statu, DISCHARGE_DIRECTION, CHARGE_DIRECTION, ENERGY_DEFAULT);
    switch(microgrid_ctrl.plan_statu) 
    {
        case DISCHARGE_DIRECTION:  /*峰电*/
            ac_start_PeakElec_process(microgrid_ctrl.en_ac_d2c, STRATAGY_TYPE_PERIOD_CTRL);
            break;
        case CHARGE_DIRECTION:     /*谷电*/
            ac_start_VallElec_process(microgrid_ctrl.en_ac_c2d, STRATAGY_TYPE_PERIOD_CTRL);
            break;
        case ENERGY_DEFAULT:       /*平电*/
            ac_start_FaltElec_process(microgrid_ctrl.en_ac_c2d, STRATAGY_TYPE_PERIOD_CTRL);
            break;
        default:
            unknow_status_standing(); //you guess...
            break;
    }
    //***** */
    if (microgrid_ctrl.plan_statu != last_paln_statu){
        last_paln_statu = microgrid_ctrl.plan_statu;
        chargefull = 0; dischargefull = 0;
        memset(battery_flag, 0, sizeof(battery_flag));
    }
}

// 光伏消纳，一定要开启防逆流，否则此功能无意义
static void ac_Photovol_Absorp(void)
{
    /* 光伏消纳策略功能概述：
        光伏优先给负载供电，不够则储能补充，若储能放空，则市电补充；光伏多余，则储能充电；
    */
    if(0 == microgrid_cfg.en_photovoltaic)
    {
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY, "当前AC微网模式，必须使能光伏!!! set_power pcs and pv = 0...");
        unknow_status_standing();
        return;
    }

    ac_start_PeakElec_process(1, STRATAGY_TYPE_PV_STORAGE);
}

// 应急备电
static void ac_Meet_Standby(void)
{
    /* 应急备电功能概述：：：：：：
        在保证不超变压器容量的前提下，储能按照最大功率充电，光伏同时给负载和储能供电（无优先级关系），不够则市电补充，若储能充满，限制光伏功率；
    */ 
    if(0 == microgrid_cfg.en_photovoltaic)
    {
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY, "当前AC微网模式，必须使能光伏!!! set_power pcs and pv = 0...");
        unknow_status_standing();
        return;
    }

    ac_start_VallElec_process(0, STRATAGY_TYPE_STANDBY);
}

static int start_ac_connect_grid_strategy(void)
{
    dev_info_all_t *var = get_dev_info_all_var();
    //inf_printf();
    accord_soc_cal_supportpower(microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_combin);

    micro_ac_log(LOG_INFO, AC_ID_0003, NULL, IS_KEY, "<策略：[%d]   %d:削峰填谷 %d:动态增容 %d:自发自用 %d:光储备电>", microgrid_ctrl.choose_func, STRATAGY_TYPE_PERIOD_CTRL, STRATAGY_TYPE_DEMAND_FIXED, STRATAGY_TYPE_PV_STORAGE, STRATAGY_TYPE_STANDBY);
    if (var->meter_grid.meter_grid_param[0].info.meter_grid_data.on_line)
    {
        micro_ac_log(LOG_INFO, AC_ID_0010, NULL, IS_KEY, "关口表在线");
        switch(mode_select())
        {
            case STRATAGY_TYPE_PERIOD_CTRL:  /*削峰填谷模式*/
                ac_Cutpeak_Fillvalley();
            break;
            case STRATAGY_TYPE_DEMAND_FIXED: /*变压器增容*/
                return 0;
                // 
            break;
            case STRATAGY_TYPE_PV_STORAGE:  /*光伏消纳*/
                ac_Photovol_Absorp();
            break;
            case STRATAGY_TYPE_STANDBY:     /*应急备电*/
                ac_Meet_Standby();
            break;
            case STRATAGY_TYPE_SURPLUS2GRID:  /*上网优先*/
                ac_Photovol_Absorp();
            break;
            default:
                {
                    double pcs_exp_power = 0, pv_target_power = 0;
                    adjust_to_target(pv_target_power, pcs_exp_power);
                    ac_set_power();  
                } 
            break;
        }
    }
    else{  // 关口表离线
        double pcs_exp_power = 0, pv_target_power = 0;
        adjust_to_target(pv_target_power, pcs_exp_power);
        ac_set_power();   
        micro_ac_log(LOG_ERR, AC_ID_0010, "grid", IS_KEY, "错误，关口表离线!!!");   
    }
    return 0;
}

static int ac_cal_off_pv_power(double *pcs_exp_power, double *pv_target_power)
{
    int dirction = 0;
    double _ptp = 0, _pcs_power = 0;
    dev_info_all_t *var = get_dev_info_all_var();
    struct _dido_t * _dido = &var->dido.dido_param[0];

    _pcs_power = 5;
    _ptp = fabs(microgrid_ctrl.charge_max_set) > microgrid_ctrl.pvMax ? microgrid_ctrl.pvMax : fabs(microgrid_ctrl.charge_max_set); // PV容量可能过大，加以限制
    micro_ac_log(LOG_INFO, AC_ID_0008, NULL, IS_KEY, "光伏目标功率(%lf) ", _ptp);

    if (microgrid_data.battery_sta == STATE_EMPTY || (microgrid_cfg.en_diesel_generator == 1 && microgrid_data.SOC_floor < microgrid_ctrl.dg_boot_soc)) {
        if (microgrid_cfg.en_diesel_generator){  // 1.使能柴发则开启柴发，柴发启动后，状态机自动进入柴发充电逻辑
#if 1
            if((microgrid_ctrl.choose_func !=  STRATAGY_TYPE_TOU || (microgrid_ctrl.choose_func == STRATAGY_TYPE_TOU && microgrid_ctrl.current_tou_info && microgrid_ctrl.current_tou_info->ChargeDG)))
            {
                atomic_store(&_dido->info.dido_ctrl.DG_ctrl, 1);
                micro_ac_log(LOG_NOTICE, AC_ID_0012, "oper", IS_KEY, "启动柴发");
            }
#endif
#if 0
            // 定制需求
            // 用于无STS，且无并离网断路器时，SOC低于柴发启动阈值，强制切入柴发并网状态，（注意：不能直接开柴发!!!，需先关机PCS，切并网后，再开启柴发-- 此步骤由柴发状态init来做）
            bit_set(microgrid_ctrl.cut_flag, BIT_STATE_CF_CONNECT_GRID, 1);
			micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "置位柴发并网标识");
#endif
        }       
        else if (microgrid_cfg.en_lcb){
            atomic_store(&_dido->info.dido_ctrl.lcb_ctrl, 0); // 2.使能负载断路器，则断开负载
            micro_ac_log(LOG_NOTICE, AC_ID_0013, "oper", IS_KEY, "断开负载断路器");
        } 
        else{
            _pcs_power = 0;
            update_pcs_switch(var, 0);           // 保护电池，PCS关机，系统将无法运行于离网模式，需要切手动模式对储能充电
            micro_ac_log(LOG_NOTICE, AC_ID_0013, "oper", IS_KEY, "保护电池，PCS关机，需人工介入!!!");
        }
    }
    else if (microgrid_data.battery_sta == STATE_OR)
    {
        if (microgrid_cfg.en_lcb){
            atomic_store(&_dido->info.dido_ctrl.lcb_ctrl, 1); // 接通负载
            micro_ac_log(LOG_NOTICE, AC_ID_0013, "oper", IS_KEY, "接通负载");
        }
    }
    else if (microgrid_data.battery_sta == STATE_FULL) {
        _ptp = 0; // 储能充满，光伏设置0功率，储能单独带载
    }

    *pcs_exp_power = _pcs_power;
#if 1
    *pv_target_power = (_ptp > microgrid_ctrl.pvMax) ? microgrid_ctrl.pvMax : _ptp;
    if (*pv_target_power < 0) *pv_target_power = 0;
#endif

    return dirction;
}

static void ac_start_off_process(void)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率
    
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "光储离网");
    
    ac_cal_off_pv_power(&pcs_exp_power, &pv_target_power);

    adjust_to_target(pv_target_power, pcs_exp_power);

    ac_set_power();
}

static void start_ac_off_grid_strategy(void)
{
    //inf_printf();
    accord_soc_cal_supportpower(microgrid_ctrl.SOC_min_netdead, microgrid_ctrl.SOC_max_netdead);
    ac_start_off_process();
}

static RELEVANCE_STATE ac_init_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    micr_action_and_check_t *action_steps = init_actions;
    int action_steps_max = ARRAY_SIZE(init_actions);

    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "初始状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_init_handover_detect(RELEVANCE_STATE state)
{
    if (microgrid_cfg.en_diesel_generator == 0 && \
        microgrid_cfg.en_photovoltaic == 0 && \
        microgrid_cfg.en_mains == 0 && \
        microgrid_cfg.en_charging_pile == 0 && \
        microgrid_cfg.en_esc == 0 && \
        microgrid_cfg.en_sts == 0 && \
        microgrid_cfg.en_icb == 0 && \
        microgrid_cfg.en_lcb == 0 && \
        microgrid_cfg.en_ats == 0)
    return state;
    micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "初始状态, 检测切出条件...");
    micr_condition_and_check_t *micr_condition_and_check = init_handover_detect;
    int size = ARRAY_SIZE(init_handover_detect);
    return micr_condition_check(micr_condition_and_check, size, state);
}

static int ac_init_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_set(microgrid_ctrl.cut_flag, BIT_STATE_INIT, 0); // 
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "初始状态行为，执行中...");
    sleep(1);
    Relevant_data_refresh();
    dev_info_all_t *var = get_dev_info_all_var();
    {
        adjust_to_target(0, 0);
        ac_set_power();

        update_pcs_switch(var, 0);
        update_pv_switch(var, 0);
    }
    // 此处可添加一些定制逻辑，用于定义进入初始状态，所需要做的动作
#if 0









#endif
    return 0;
}

static RELEVANCE_STATE ac_await_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    micr_action_and_check_t *action_steps = await_init_actions;
    int action_steps_max = 0;
    if (microgrid_cfg.en_sts){
        action_steps = await_init_actions_sts;
        action_steps_max = 0;
    }else{
        action_steps = await_init_actions;
        action_steps_max = ARRAY_SIZE(await_init_actions);
    }
    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "待机状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_await_handover_detect(RELEVANCE_STATE state)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "待机状态, 检测切出条件...");
    micr_condition_and_check_t *micr_condition_and_check = await_handover_detect;
    int size = ARRAY_SIZE(await_handover_detect);
    return micr_condition_check(micr_condition_and_check, size, state);
}

static int ac_await_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_set(microgrid_ctrl.cut_flag, BIT_STATE_AWAIT, 0); // 
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "待机状态行为，执行中...");
    sleep(1);
    Relevant_data_refresh();
    dev_info_all_t *var = get_dev_info_all_var();
    {
        adjust_to_target(0, 0);
        ac_set_power();

        update_pcs_switch(var, 0);
        update_pv_switch(var, 0);
    }
	// 此处可添加一些定制逻辑，用于定义进入待机状态，所需要做的动作
#if 0









#endif

    return 0;
}

static RELEVANCE_STATE ac_abnormal_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    micr_action_and_check_t *action_steps = abnormal_init_actions;
    int action_steps_max = ARRAY_SIZE(abnormal_init_actions);
    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "异常状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_abnormal_handover_detect(RELEVANCE_STATE state)
{
    int find = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();

    if(dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS)){ 
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "EMS系统状态异常，异常状态字: %d", dev_get_dev_tag_int(DEV_NO_EMS, SYSTEM_STATUS_W)); 
        return state; 
    }

    if (microgrid_data.on_line == 0) {
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "所有LC都离线 lc_num: %d", _dev_info_all->cabinet_info.num);
        return state; 
    }

    //if (microgrid_abnormal.DG_abnormal != 0 || microgrid_abnormal.icb_abnormal != 0 || microgrid_abnormal.lcb_abnormal != 0){ return state; }

    for (int i = 0 ; i < _dev_info_all->cabinet_info.num; i++) // 系统状态运行正常，且至少有一个柜子可以用，就可以检查切出
	{
	    cabinet_inside_t *_cabinet_inside = _dev_info_all->cabinet_info.cabinet_inside[i];
        if (_cabinet_inside->cab_data.on_line == 1 && _cabinet_inside->cab_data.en == 0){
            find = 1; 
            break;
        }
	}
    if (find){
        micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "异常状态, 检测切出条件...");
        micr_condition_and_check_t *micr_condition_and_check = abnormal_handover_detect;
        int size = ARRAY_SIZE(abnormal_handover_detect);
        return micr_condition_check(micr_condition_and_check, size, state);
    }
    else{
        micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "所有LC都离线或不可用，请排查网络或检查LC系统装态, lc_num: %d", _dev_info_all->cabinet_info.num);
        return state;
    }
}

static int ac_abnormal_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_clean(microgrid_ctrl.cut_flag);
    //bit_set(microgrid_ctrl.cut_flag, BIT_STATE_ABNORMAL, 0); //
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "异常状态行为，执行中...");
    sleep(1);
    Relevant_data_refresh();
    dev_info_all_t *var = get_dev_info_all_var();
    {
        adjust_to_target(0, 0);
        ac_set_power();

        update_pcs_switch(var, 0);
        update_pv_switch(var, 0);
    }
	// 此处可添加一些定制逻辑，用于定义进入异常状态，所需要做的动作
#if 0









#endif
	
    return 0;
}

static RELEVANCE_STATE ac_grid_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    int action_steps_max = 0;
    micr_action_and_check_t *action_steps = NULL;
    if (microgrid_cfg.en_sts){
        action_steps = grid_init_actions_sts;
        action_steps_max = ARRAY_SIZE(grid_init_actions_sts);
    }
    else{
        action_steps = grid_init_actions;
        action_steps_max = ARRAY_SIZE(grid_init_actions);
    }
    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "市电并网状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_grid_handover_detect(RELEVANCE_STATE state)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "市电并网状态, 检测切出条件...");
    micr_condition_and_check_t *micr_condition_and_check = grid_handover_detect;
    int size = ARRAY_SIZE(grid_handover_detect);
    return micr_condition_check(micr_condition_and_check, size, state);
}

static int ac_grid_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_set(microgrid_ctrl.cut_flag, BIT_STATE_CONNECT_GRID, 0); //
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "市电并网状态行为, 执行中...");
    usleep(1000 * 1000);  // 由于数采频率及电网表自身采集效率，建议算法周期1秒，电网表、PCS、光伏跟功率相关的poll采集周期500ms.算法周期太短，可能会出现数据刷新不及时导致超调问题

    if(Relevant_data_refresh()){
        return 0;
    }

    if (microgrid_data.grid_statu == 1)
        start_ac_connect_grid_strategy();
    else
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "pcs is not Grid status, waiting...");
    return 0;
}


static RELEVANCE_STATE ac_off_grid_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    int action_steps_max = 0;
    micr_action_and_check_t *action_steps = NULL;
    if (microgrid_cfg.en_sts){
        action_steps = offgrid_init_actions_sts;
        action_steps_max = ARRAY_SIZE(offgrid_init_actions_sts);
    }
    else{
        action_steps = offgrid_init_actions;
        action_steps_max = ARRAY_SIZE(offgrid_init_actions);
    }
    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "离网状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_off_grid_handover_detect(RELEVANCE_STATE state)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "离网状态, 检测切出条件...");
    micr_condition_and_check_t *micr_condition_and_check = offgrid_handover_detect;
    int size = ARRAY_SIZE(offgrid_handover_detect);
    return micr_condition_check(micr_condition_and_check, size, state);
}

static int ac_off_grid_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_set(microgrid_ctrl.cut_flag, BIT_STATE_OFF_GRID, 0); //
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "离网状态行为，执行中...");
    usleep(1000 * 1000); 

    if(Relevant_data_refresh()){
        return 0;
    }

    if (microgrid_data.offgrid_statu == 1)
        start_ac_off_grid_strategy();
    else
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "pcs is not offgrid status, waiting...");
    return 0;
}

static RELEVANCE_STATE ac_cfgrid_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    int action_steps_max = 0;
    micr_action_and_check_t *action_steps = NULL;
    if (microgrid_cfg.en_sts){
        action_steps = cf_grid_init_actions_sts;
        action_steps_max = ARRAY_SIZE(cf_grid_init_actions_sts);
    }
    else{
        action_steps = cf_grid_init_actions;
        action_steps_max = ARRAY_SIZE(cf_grid_init_actions);
    }
    micro_ac_log(LOG_NOTICE, AC_ID_0016, "init", IS_KEY, "柴发并网状态, 初始化中...");
    return excute_action_steps(action_steps, &ac_state_machine.state[state].action_step_idx, action_steps_max);
}

static RELEVANCE_STATE ac_cfgrid_handover_detect(RELEVANCE_STATE state)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0015, "check", IS_KEY, "柴发并网状态, 检测切出条件...");
    micr_condition_and_check_t *micr_condition_and_check = cf_grid_handover_detect;
    int size = ARRAY_SIZE(cf_grid_handover_detect);
    return micr_condition_check(micr_condition_and_check, size, state);
}

static int ac_cal_cf_pv_power(double *pcs_exp_power, double *pv_target_power)
{
    int dirction = 0;
    double _ptp = 0;
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();
    double cf_act_power = _dev_info_all->meter_dg.meter_dg_param[0].info.meter_dg_data.act_power;
    double charge_limit = 0, discharge_limit = 0;

    cal_support_power(&charge_limit, &discharge_limit, -1, -1);
    double _Pmlmax = microgrid_ctrl.dg_rated_power;
    double _exp_power = xl_antiReflux(  // 柴发保护，在保证不超柴发额定功率的前提下，尽可能靠近充电功率上限
        cf_act_power, 
        _Pmlmax,  
        1, 
        0, 
        charge_limit, 
        microgrid_data.pcs_power, 
        _Pmlmax - microgrid_ctrl.DgDiff,
        0);
    micro_ac_log(LOG_NOTICE, AC_ID_0008, NULL, IS_KEY, "储能充电功率 %lf", _exp_power);
 
    dirction = CHARGE_DIRECTION;
    power_limit(&_exp_power, &_ptp, dirction, -1, -1);

    *pcs_exp_power = _exp_power; *pv_target_power = _ptp;
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "pcs_exp_power: %lf, pv_target_power: %lf", *pcs_exp_power, *pv_target_power);
    return dirction;
}

static void ac_start_cf_process(void)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率

    dev_info_all_t *var = get_dev_info_all_var();
    struct _dido_t * _dido = &var->dido.dido_param[0];
    
    ac_cal_cf_pv_power(&pcs_exp_power, &pv_target_power);
    
    adjust_to_target(pv_target_power, pcs_exp_power);
    
    if (microgrid_ctrl.charge_max_set == 0){ 
        if (microgrid_cfg.en_diesel_generator){  // 储能满充后，关闭柴发，进入离网状态
#if 1
            atomic_store(&_dido->info.dido_ctrl.DG_ctrl, 0);
            micro_ac_log(LOG_NOTICE, AC_ID_0012, "oper", IS_KEY, "储能满充后，关闭柴发");
#endif
#if 0
            bit_set(microgrid_ctrl.cut_flag, BIT_STATE_OFF_GRID, 1); // 适用于无STS和并离网断路器时，需在离网和柴发并网之前切换的场景
			micro_ac_log(LOG_NOTICE, AC_ID_0032, NOT_KEY,  "置位离网标识");
#endif
        } 
    }
    ac_set_power();
}

// 柴发应急备电
static int ac_cfgrid_behaviour_func(RELEVANCE_STATE state_self)
{
    bit_set(microgrid_ctrl.cut_flag, BIT_STATE_CF_CONNECT_GRID, 0); //
    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "柴发并网状态行为，执行中...");
    usleep(1000 * 1000); 

    if(Relevant_data_refresh()){
        return 0;
    }

    //inf_printf();
    accord_soc_cal_supportpower(microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_combin);
    ac_start_cf_process();
    return 0;
}

static RELEVANCE_STATE states_switch_exev(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    double pcs_exp_power = 0;
    double pv_target_power = 0; //光伏目标功率

    micro_ac_log(LOG_NOTICE, AC_ID_0014, "exec", IS_KEY, "状态切换，设置PCS，光伏0功率!!!");
    adjust_to_target(pv_target_power, pcs_exp_power);
    ac_set_power();
    return state;
}

static void states_exit(current_stat_t *state_machine)
{
    if(NULL == state_machine->states_exit)
    {
        return;
    }
    state_machine->states_exit(state_machine->last_state, state_machine->major_state);
}

static void ac_state_machine_Init(current_stat_t *_ac_state_machine)
{
    _ac_state_machine->state[STATE_INIT].handover_detect = ac_init_handover_detect;
    _ac_state_machine->state[STATE_INIT].behaviour_func = ac_init_behaviour_func;
    _ac_state_machine->state[STATE_INIT].init = ac_init_init;
    _ac_state_machine->state[STATE_INIT].state_self = STATE_INIT;
    _ac_state_machine->state[STATE_INIT].action_step_idx = 0;

    _ac_state_machine->state[STATE_AWAIT].handover_detect = ac_await_handover_detect;
    _ac_state_machine->state[STATE_AWAIT].behaviour_func = ac_await_behaviour_func;
    _ac_state_machine->state[STATE_AWAIT].init = ac_await_init;
    _ac_state_machine->state[STATE_AWAIT].state_self = STATE_AWAIT;
    _ac_state_machine->state[STATE_AWAIT].action_step_idx = 0;

    _ac_state_machine->state[STATE_CONNECT_GRID].handover_detect = ac_grid_handover_detect;
    _ac_state_machine->state[STATE_CONNECT_GRID].behaviour_func = ac_grid_behaviour_func;
    _ac_state_machine->state[STATE_CONNECT_GRID].init = ac_grid_init;
    _ac_state_machine->state[STATE_CONNECT_GRID].state_self = STATE_CONNECT_GRID;
    _ac_state_machine->state[STATE_CONNECT_GRID].action_step_idx = 0;

    _ac_state_machine->state[STATE_OFF_GRID].handover_detect = ac_off_grid_handover_detect;
    _ac_state_machine->state[STATE_OFF_GRID].behaviour_func = ac_off_grid_behaviour_func;
    _ac_state_machine->state[STATE_OFF_GRID].init = ac_off_grid_init;
    _ac_state_machine->state[STATE_OFF_GRID].state_self = STATE_OFF_GRID;
    _ac_state_machine->state[STATE_OFF_GRID].action_step_idx = 0;

    _ac_state_machine->state[STATE_CF_CONNECT_GRID].handover_detect = ac_cfgrid_handover_detect;
    _ac_state_machine->state[STATE_CF_CONNECT_GRID].behaviour_func = ac_cfgrid_behaviour_func;
    _ac_state_machine->state[STATE_CF_CONNECT_GRID].init = ac_cfgrid_init;
    _ac_state_machine->state[STATE_CF_CONNECT_GRID].state_self = STATE_CF_CONNECT_GRID;
    _ac_state_machine->state[STATE_CF_CONNECT_GRID].action_step_idx = 0;

    _ac_state_machine->state[STATE_ABNORMAL].handover_detect = ac_abnormal_handover_detect;
    _ac_state_machine->state[STATE_ABNORMAL].behaviour_func = ac_abnormal_behaviour_func;
    _ac_state_machine->state[STATE_ABNORMAL].init = ac_abnormal_init;
    _ac_state_machine->state[STATE_ABNORMAL].state_self = STATE_ABNORMAL; 

    /*未定义状态无法确定逻辑*/
    _ac_state_machine->state[STATE_DEFAULT].handover_detect = NULL;
    _ac_state_machine->state[STATE_DEFAULT].behaviour_func = NULL;
    _ac_state_machine->state[STATE_DEFAULT].init = NULL;
    _ac_state_machine->state[STATE_DEFAULT].state_self = STATE_DEFAULT; 

    _ac_state_machine->states_exit = states_switch_exev;
    state_switch(_ac_state_machine, STATE_INIT); //>> 初始状态，准备 
}

/**控制***************************************************************************************************************************START*********/
static int ac_chk_pcs_connection(dev_info_all_t *var, int idx, int value)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "chk cab grp[%d] connection= %d, %d", idx, value, var->cabinet_info.cabinet_inside[idx]->cab_data.connect);
    if(value == MICR_ACTION_TYPE_INIT || var->cabinet_info.cabinet_inside[idx]->cab_data.connect == MICR_ACTION_TYPE_INIT) 
        return MICR_CONDITION_SKIP;
    else 
        return (var->cabinet_info.cabinet_inside[idx]->cab_data.connect == value)? MICR_CONDITION_OK: MICR_CONDITION_NO_MATCH;
}

static void ac_send_pcs_connection(dev_info_all_t *var, int idx, int value)
{
    dev_set_dev_tag_int(DEV_NO_EMS, SET_CONNECT, value);
    dev_set_dev_tag_int(var->cabinet_info.cabinet_inside[idx]->no, SET_CONNECT, value);  // 0:Off-grid;1:On-grid
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "Cab: %s :Set grp[%d] connection = %d", var->cabinet_info.cabinet_inside[idx]->no, idx, value);
}

static int ac_chk_pcs_switch(dev_info_all_t *var, int idx, int value)
{
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "chk cab grp[%d] status= %d, %d", idx, value, var->cabinet_info.cabinet_inside[idx]->cab_data.onoff);
    if(value == MICR_ACTION_TYPE_INIT || var->cabinet_info.cabinet_inside[idx]->cab_data.onoff == MICR_ACTION_TYPE_INIT) 
        return MICR_CONDITION_SKIP;
    else 
        return (var->cabinet_info.cabinet_inside[idx]->cab_data.onoff == value)? MICR_CONDITION_OK: MICR_CONDITION_NO_MATCH;
}

static void ac_send_pcs_switch(dev_info_all_t *var, int idx, int value)
{
    dev_set_dev_tag_int(DEV_NO_EMS, ON_OFF_STATE, value);
    dev_set_dev_tag_int(var->cabinet_info.cabinet_inside[idx]->no, ON_OFF_STATE, value); // 0:Off;1:On
    micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY, "Cab: %s :Set grp[%d] status = %d", var->cabinet_info.cabinet_inside[idx]->no, idx, value);
}

static double chk_avail_power_modified(dev_info_all_t *var, int grp_idx, double value, int zero_flag) // 0:Normal;1:Abnormal;
{
    double avail_power = 0;
    double tmp = value;

    if(value > 0){// 放电
        if (microgrid_ctrl.en_bms_power_limit){
            avail_power =  var->cabinet_info.cabinet_inside[grp_idx]->cab_ctrl.pcs_discharge_max_actual;
            micro_ac_log(LOG_NOTICE, AC_ID_0022, var->cabinet_info.cabinet_inside[grp_idx]->no, IS_KEY,  "放电限制, grp[%d] [bms最大可放功率, 放电功率][%f, %f]", grp_idx, avail_power, tmp);
            tmp = MIN(avail_power, tmp);
        }
        if(zero_flag == 1) tmp = 0;
    }
    else if(value < 0) // 充电
    {
        if (microgrid_ctrl.en_bms_power_limit){
            avail_power =  var->cabinet_info.cabinet_inside[grp_idx]->cab_ctrl.pcs_charge_max_actual;
            micro_ac_log(LOG_NOTICE, AC_ID_0022, var->cabinet_info.cabinet_inside[grp_idx]->no, IS_KEY,  "充电限制, grp[%d] [bms最大可充功率, 充电功率][%f, %f]", grp_idx, avail_power, tmp);
            tmp = MAX(avail_power, tmp);
        }
        if(zero_flag == 1) tmp = 0;
    }
    else { 

    } 
    return tmp;
}

static void *cabinet_loop(void *param)
{
    dev_info_all_t *var = ((ctrl_thread_var_t *)param)->var;
    cabinet_inside_t **grp = ((ctrl_thread_var_t *)param)->grp;
    int grp_idx = ((void*)grp - (void*)&var->cabinet_info.cabinet_inside[0]) / sizeof(void*);

    int i = 0;
    time_t last_update_status = 0, last_update_power = 0;
    time_t last_update_pv_power = 0, last_update_pv_onoff = 0;
    time_t last_update_lcb = 0, last_update_DG = 0;
    // time_t last_update_icb = 0;

    double last_power = -1;
    double last_pv_power = -1;
	int last_pv_onoff = -1;
    int last_lcb = -1, last_DG = -1, last_icb = -1;

    int cab_ctrl_onoff = -1, cab_ctrl_connect = -1, pv_exp_onoff = -1;
    double pcs_exp_power = 0, pv_exp_power = 0;
    int lcb_ctrl = -1, DG_ctrl = -1, icb_ctrl = -1;
    struct _dido_t * _dido = &var->dido.dido_param[0];
    int times = 0;
    int exec_powerzeor = 0;
    while (1)
    {  
        // cabinet 避免读到中间状态，（如撕裂读，Torn Read）
        cab_ctrl_onoff = atomic_load(&(*grp)->cab_ctrl.onoff);  cab_ctrl_connect = atomic_load(&(*grp)->cab_ctrl.connect);
        pcs_exp_power = atomic_load(&(*grp)->cab_ctrl.pcs_exp_power);
        // pv
        pv_exp_onoff = atomic_load(&microgrid_ctrl.pv_exp_onoff);  pv_exp_power = atomic_load(&microgrid_ctrl.pv_exp_power);
        // dido ctrl
        lcb_ctrl = atomic_load(&_dido->info.dido_ctrl.lcb_ctrl); DG_ctrl = atomic_load(&_dido->info.dido_ctrl.DG_ctrl); icb_ctrl = atomic_load(&_dido->info.dido_ctrl.icb_ctrl);
        
        if (microgrid_ctrl.ControlMode != EMS_AUTO_MODE){ 
            sleep(1);
            continue;
        }
        
        times++;
        if (TOU_userdef_mode())
        {
            if (times > 4) {
                execute_TOU_userdef();
                times = 0;
            }
            exec_powerzeor++;
            sleep(1);
            if (exec_powerzeor > 2)
            {
                continue;
            }
            else
            {
                pcs_exp_power = 0;
                pv_exp_power = 0;
            }
        }
        else
        {
            exec_powerzeor = 0;
        }

        usleep(250 * 1000);
        time_t now = time(NULL);

        if(ac_chk_pcs_switch(var, grp_idx, cab_ctrl_onoff) == MICR_CONDITION_NO_MATCH){
            if(now >= last_update_status + 3){
                last_update_status = now;
                ac_send_pcs_switch(var, grp_idx, cab_ctrl_onoff);
            }
        }  
        else if(microgrid_cfg.en_sts == 0 && ac_chk_pcs_connection(var, grp_idx, cab_ctrl_connect) == MICR_CONDITION_NO_MATCH){ // 不使能STS，才开启并离网守护
            if(now >= last_update_status + 3){ //防抖~~
                last_update_status = now;
                ac_send_pcs_connection(var, grp_idx, cab_ctrl_connect);
            }
        }

        if (grp_idx == 0){ // 光伏逆变器统一在第一个柜子(主柜)线程去控制，所以必须使能主从模式，光伏逆变器可挂在任意柜子下
            if(var->pv.num > 0){
                if (last_pv_onoff != pv_exp_onoff || now >= (last_update_pv_onoff + 5)){
                    last_update_pv_onoff = now;
                    last_pv_onoff = pv_exp_onoff;
                    for (i = 0; i < var->pv.num; i++){
                        pe_set_onoff(var->pv.pv_param[i].no, pv_exp_onoff);
                        micro_ac_log(LOG_NOTICE, AC_ID_0021, var->pv.pv_param[i].no, IS_KEY,  "Pv设备：%s: 设置 grp[%d] 开关机: %d ", var->pv.pv_param[i].no, i, pv_exp_onoff);
                    }
                }
                if (microgrid_ctrl.EnPvPrectrl == 0){
                    if(((last_pv_power - 0.5) > pv_exp_power || (last_pv_power + 0.5) < pv_exp_power) || \
                        now >= (last_update_pv_power + 10)){   //设置光伏 功率/百分比(百分比放到模版里面做，此处全是功率)
                        last_update_pv_power = now;
                        last_pv_power = pv_exp_power;
                        struct Photovoltaic_power_adjust inf = {0};

                        Photovoltaic_adjust_init(&inf, pv_exp_power, microgrid_ctrl.mppt_eq, microgrid_ctrl.mppt_eq_tl, microgrid_ctrl.mppt_eq_rt, var->pv.num);
        
                        for (i = 0; i < var->pv.num; i++){
                            Photovoltaic_adjust_info_set_data(&inf, var->pv.pv_param[i].info.pv_data.power, (double)1 / var->pv.num, i);
                        }
                        Photovoltaic_regulation_algorithm(&inf);    // 算法调用
                        for (i = 0; i < var->pv.num; i++){
                            var->pv.pv_param[i].info.pv_ctrl.power_set = inf.info[i].power_set > (microgrid_ctrl.pvMax * var->pv.pv_param[i].info.pv_cfg.scale) ? (microgrid_ctrl.pvMax * var->pv.pv_param[i].info.pv_cfg.scale) : inf.info[i].power_set;
                            pe_set_power(var->pv.pv_param[i].no, atomic_load(&var->pv.pv_param[i].info.pv_ctrl.power_set));
                            micro_ac_log(LOG_NOTICE, AC_ID_0020, var->pv.pv_param[i].no, IS_KEY,  "Pv设备：%s :设置 grp[%d] 功率/百分比 : %.3f ", var->pv.pv_param[i].no, i, atomic_load(&var->pv.pv_param[i].info.pv_ctrl.power_set));
                        }
                    
                        if(inf.info)
                        {
                            free(inf.info);
                        }
                    }
                }
                else{ // 禁用光伏精细化控制
                    if(((last_pv_power - 0.5) > pv_exp_power || (last_pv_power + 0.5) < pv_exp_power) || \
                        now >= (last_update_pv_power + 30)){   //设置光伏 功率/百分比(百分比放到模版里面做，此处全是功率)
                        last_update_pv_power = now;
                        last_pv_power = pv_exp_power;
                        for (i = 0; i < var->pv.num; i++){
                            pe_set_power(var->pv.pv_param[i].no, atomic_load(&var->pv.pv_param[i].info.pv_ctrl.power_set));
                            micro_ac_log(LOG_NOTICE, AC_ID_0020, var->pv.pv_param[i].no, IS_KEY,  "Pv设备：%s :设置 grp[%d] 功率/百分比 : %.3f ", var->pv.pv_param[i].no, i, atomic_load(&var->pv.pv_param[i].info.pv_ctrl.power_set));
                        }
                    }                     
                }
            }
            // 负载断路器 0: 断开  1:闭合 \柴发控制 0: 停止  1:启动 \并离网断路器 0: 断开  1:闭合  --底层控制方式：DIDO/modbus协议，但对于EMS上层都是点位，动环xlsx表映射决定控制方式
            if ( microgrid_cfg.en_lcb && (last_lcb != lcb_ctrl || now >= (last_update_lcb + 60)) ) { 
                last_update_lcb = now;
                last_lcb = lcb_ctrl;
                dev_set_dev_tag_int(DEV_NO_EMS, LCB_CTRL, lcb_ctrl);
            }
            if ( microgrid_cfg.en_diesel_generator && (last_DG != DG_ctrl || now >= (last_update_DG + 60)) ){
                last_update_DG = now;
                last_DG = DG_ctrl;
                dev_set_dev_tag_int(DEV_NO_EMS, DG_CTRL, DG_ctrl); 
            }  
            //if ( microgrid_cfg.en_icb && (last_icb != icb_ctrl || now >= (last_update_icb + 60)) ){
            if ( microgrid_cfg.en_icb && (last_icb != icb_ctrl)){
                // last_update_icb = now;
                last_icb = icb_ctrl;
                dev_set_dev_tag_int(DEV_NO_EMS, ICB_CTRL, icb_ctrl); 
            }     
        }

        double avail_power = chk_avail_power_modified(var, grp_idx, pcs_exp_power, (*grp)->cab_data.en);
        if(last_power != avail_power || now >= last_update_power + 30)
        {
            last_update_power = now;
            last_power = avail_power;
            
            // 分相模式下，分别下发各相功率
            if (microgrid_ctrl.phase_reflux == 1) {
                double phase_a_power = (*grp)->cab_ctrl.pcs_exp_phasepower[PHASE_A];
                double phase_b_power = (*grp)->cab_ctrl.pcs_exp_phasepower[PHASE_B];
                double phase_c_power = (*grp)->cab_ctrl.pcs_exp_phasepower[PHASE_C];
                dev_set_dev_tag_float((*grp)->no, SET_ACT_POWER, avail_power);
                double total_power = phase_a_power + phase_b_power + phase_c_power;
                if (total_power > avail_power) {
                    phase_a_power = phase_a_power * avail_power / total_power;
                    phase_b_power = phase_b_power * avail_power / total_power;
                    phase_c_power = phase_c_power * avail_power / total_power;
                }
                dev_set_dev_tag_float((*grp)->no, SET_PHASE_A_POWER, phase_a_power);
                dev_set_dev_tag_float((*grp)->no, SET_PHASE_B_POWER, phase_b_power);
                dev_set_dev_tag_float((*grp)->no, SET_PHASE_C_POWER, phase_c_power);
                micro_ac_log(LOG_NOTICE, INIT_ID_0000, NOT_KEY, "Cab: %s :Set grp[%d] 分相功率 A=%.3f, B=%.3f, C=%.3f", 
                    var->cabinet_info.cabinet_inside[grp_idx]->no, grp_idx, phase_a_power, phase_b_power, phase_c_power);
            } else {
                dev_set_dev_tag_float((*grp)->no, SET_ACT_POWER, avail_power);
                micro_ac_log(LOG_NOTICE, INIT_ID_0000, NOT_KEY,  "Cab: %s :Set grp[%d] avail_power = %.3f ", var->cabinet_info.cabinet_inside[grp_idx]->no, grp_idx, avail_power);
            }
        }
    }

    return NULL;
}

static ctrl_thread_var_t threads_var[CABINET_NUM_MAX] = {0};
static int microgrid_cabinet_ctrl_init(dev_info_all_t *var)
{
    int index = 0;

    for(index = 0; index < var->cabinet_info.num; index++)
    {
        cabinet_inside_t **grp = &var->cabinet_info.cabinet_inside[index];
        threads_var[index].var = var;
        threads_var[index].grp = grp;
        /* 创建一个单独的线程 */
        int ret = pthread_create(&((*grp)->action_thread), NULL, cabinet_loop, &threads_var[index]);
        if (ret < 0) {
            micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "failed to created cabinet_loop %s\n", strerror(errno));
            return -1;
        }
    }
    return 0;
}
/***************************************************************************************************************************************END*****/
static int _state_init(current_stat_t *state_machine)
{
    int ret = 0;
    
    usleep(1000 * 1000);
    if(state_machine->state[state_machine->major_state].init)
        ret = state_machine->state[state_machine->major_state].init(state_machine->last_state, state_machine->major_state);
    else
    {
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "Err state_init: state:%d init unregistered", state_machine->major_state);
        return -1;
    }
    return ret;
}

void *ac_state_machine_pthread(void *args)
{
    int ret = 0, ready = 0, count = 0;
    int once = 0;
    current_stat_t *state_machine = (current_stat_t *)args;

    if(NULL == state_machine)
    {
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "ac_state_machine is NULL!!!");
        goto END;
    }

    while (1)
    { 
        inf_printf();
        // 当前单相防逆流只做了计划模式，没做自发自用，后续补充
        if (state_machine->major_state == STATE_CONNECT_GRID && microgrid_ctrl.ControlMode == EMS_AUTO_MODE && microgrid_ctrl.EnPhaseCtrl == 1)
        {
            microgrid_ctrl.phase_reflux = 1;
        }
        else 
        {
            microgrid_ctrl.phase_reflux = 0;
        }
        if (microgrid_ctrl.ControlMode != EMS_AUTO_MODE){
            if(once < 1)
            {
                once++;
            }
            else {
            /*TODO*/
            }
            Relevant_data_refresh();
            micro_ac_log(LOG_NOTICE, AC_ID_0001, "hint", IS_KEY, "温馨提示: 当前控制模式为手动模式, 请切自动模式运行策略!!!");
		    bit_clean(microgrid_ctrl.cut_flag);
            //
            chargefull = 0; dischargefull = 0;
            memset(battery_flag, 0, sizeof(battery_flag));
            //
            ready = 0;
            state_switch(state_machine, STATE_INIT); //>> 初始状态，准备 
            for(int i = 0; i < _STATE_MAX; i++)
            {   
                struct STATE_INFO *state = &state_machine->state[i];
                state->action_step_idx = 0;  
            }            
            sleep(1);
            fwrite_flush_UD_log(ac_micro_log); // 刷新日志
            fwrite_flush_UD_log(micro_log);

            continue;
        }
        
        if (TOU_userdef_mode())
        {
            execute_TOU_userdef();
            sleep(1);
            continue;
        }

        once = 0;
        micro_ac_log(LOG_NOTICE, AC_ID_0001, "hint", IS_KEY, "自动模式运行...");

        if(ready == 0){ // 1. 执行状态初始化步骤
            ready = _state_init(state_machine);
            if(-1 == ready){ // init注册异常
                sleep(1);
                continue;
            }
        }

        dev_set_dev_tag_int(DEV_NO_EMS, STATE_MACHINE, state_machine->major_state);
        if (count >= 10) {
            micro_ac_log(LOG_NOTICE, AC_ID_0002, NULL, IS_KEY, "状态机当前状态 :%s [%d]!!!", micro_state_tab[state_machine->major_state], state_machine->major_state);
            count = 0;
        }

        ret = state_check_and_switch(state_machine); // 2. 注意：在执行actions step过程中需要同时进行状态检查，满足条件即可切出
        if(1 == ret){
            ready = 0;
            //
            chargefull = 0; dischargefull = 0;
            memset(battery_flag, 0, sizeof(battery_flag));
            //
            states_exit(state_machine); // 状态切换时PCS、PV写0功率，等ready完毕，执行后续策略逻辑进行功率调度
        }

        if (microgrid_ctrl.ControlMode == EMS_AUTO_MODE){ 
            if (ready == 1){ // 3. 状态初始化步骤执行完毕，才可执行对应策略
                if(state_machine->state[state_machine->major_state].behaviour_func){
                    state_machine->state[state_machine->major_state].behaviour_func(state_machine->major_state);
                }
                else
                    micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "Err:state:%d : behaviour_func unregistered", state_machine->major_state);
            }
        }
        else
            micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "control mode is not auto!!!, ControlMode :%d", microgrid_ctrl.ControlMode);

        count++;
        SocrearlyWarning();
        fwrite_flush_UD_log(ac_micro_log);  // 刷新日志
        fwrite_flush_UD_log(micro_log);

    }
END:
    while (1)
    {
        sleep(1);
        micro_ac_log(LOG_ERR, AC_ID_0032, NULL, NOT_KEY,  "Err:The state machine thread terminates!!!");
    }
    
    return NULL;
}

static void ac_microgrid_param_Init(void){  //初始化参数
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();

    for (int i = 0 ; i < _dev_info_all->cabinet_info.num; i++){
	    cabinet_inside_t *_cabinet_inside = _dev_info_all->cabinet_info.cabinet_inside[i];
        _cabinet_inside->cab_data.on_line = 1;
        _cabinet_inside->cab_data.onoff = -1;
        _cabinet_inside->cab_data.connect = -1;
        atomic_store(&_cabinet_inside->cab_ctrl.onoff, -1);
        atomic_store(&_cabinet_inside->cab_ctrl.connect, -1);
        atomic_store(&_cabinet_inside->cab_ctrl.pcs_exp_power, 0);
        for (int phase = 0; phase < PHASE_MAX; phase++) {
            _cabinet_inside->cab_ctrl.pcs_exp_phasepower[phase] = 0;
        }
        _cabinet_inside->cab_ctrl.pcs_discharge_max_actual = 100; // 标准储能柜
        _cabinet_inside->cab_ctrl.pcs_charge_max_actual = -100;
        _cabinet_inside->cab_cfg.capacity = 100;  // 默认柜容量100KWH
	}

    for (int i = 0 ; i < _dev_info_all->pv.num; i++){
	    struct _pv_t *_pv = &_dev_info_all->pv.pv_param[i];
        _pv->info.pv_ctrl.power_set = 0;
	}

    atomic_store(&microgrid_ctrl.Grid_offgrid, -1);
    atomic_store(&microgrid_ctrl.onoff, -1);
    atomic_store(&microgrid_ctrl.pcs_exp_power, 0);
    atomic_store(&microgrid_ctrl.pv_exp_power, 0);
    atomic_store(&microgrid_ctrl.pv_exp_onoff, -1);
    microgrid_ctrl.cut_flag = bit_new(128);

    microgrid_data.grid_statu = -1;
    microgrid_data.offgrid_statu = -1;
    microgrid_data.on_statu = -1;
    microgrid_data.off_statu = -1;
    microgrid_data.pv_on_statu = -1;
    microgrid_data.pv_off_statu = -1;

    atomic_store(&_dev_info_all->dido.dido_param[0].info.dido_ctrl.icb_ctrl, -1);
    atomic_store(&_dev_info_all->dido.dido_param[0].info.dido_ctrl.lcb_ctrl, -1);
    atomic_store(&_dev_info_all->dido.dido_param[0].info.dido_ctrl.DG_ctrl, -1);
    _dev_info_all->dido.dido_param[0].info.dido_data.conn_sign = -1;
    _dev_info_all->dido.dido_param[0].info.dido_data.ats_sign = -1;
    _dev_info_all->dido.dido_param[0].info.dido_data.lcb_sign = -1;
    _dev_info_all->dido.dido_param[0].info.dido_data.icb_sign = -1;
    _dev_info_all->dido.dido_param[0].info.dido_data.DG_sign = -1;

    ac_cab_scale_calculate(); // 初步计算各柜子比例，进而计算各柜子的最大充放电功率
}

static int set_micro_log_en(struct UD_log *self)
{
    // return ud_log_Level & UD_LOG_MICRO ? TRUE : FALSE;

    return ud_log_Level & 0x002 ? TRUE : FALSE;
}

int start_ac_microgrid(void)
{
	current_stat_t *_ac_state_machine = get_ac_state_machine();
    dev_info_all_t *_dev_info_all = get_dev_info_all_var();

    ac_microgrid_param_Init();

    microgrid_cabinet_ctrl_init(_dev_info_all);
    ac_state_machine_Init(_ac_state_machine); 

    ac_micro_log = UD_log_creat("micro.log", set_micro_log_en);
    pthread_t tid = {0};
    if (pthread_create(&tid, NULL, ac_state_machine_pthread, _ac_state_machine) != 0){
		micro_ac_log(LOG_NOTICE, AC_ID_0032, NULL, NOT_KEY,  "Failed to create state_machine_pthread thread!");
		return -1;
	}
	else
	{
		pthread_setname_np(tid, "ac_microgrid");
	}
	
    return 0;
}

