/*
 * @Author: zchuo zhengchen.huo@lnxall.com
 * @Date: 2024-12-05 11:17:42
 * @LastEditors: ybzhou yibo.zhou@lnxall.com
 * @LastEditTime: 2026-03-28 15:08:29
 * @FilePath: /proto_forward/src/ems/microgridtopology_dc.c
 * @Description: 微网直流侧并网业务代码 在本环境中大部分功能均专用于本环境业务逻辑实现 并与其他业务逻辑区别隔离开来
 * 
 * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. 
 */
#include "define.h"
#include "log_upper_data.h"
#include "microgridtopology.h"
#include "collector-api.h"
#include "deviceLayer.h" 
#include "emsctrlProc.h"
#include "discover.h"
#include "./jsonct.h"
#include "deviceLayer.h"
#include <math.h>
#include <sys/syslog.h>
#include <time.h>
#include <unistd.h>
#include "lnxall_buffer.h"
#include "../business_log/business_log.h"

double xl_exp_power = 0;
current_stat_t state_machine_Micgp;

/**
 * @description: 单个柜子的MPPT期望门限功率
 * @return {*}
 */
int mppt_exp_power_set(cabinet_inside_t *cab, void *mppt_power_all)
{
    cab->cab_ctrl.mppt_exp_power = cab->cab_ctrl.pcs_exp_power - cab->cab_ctrl.bms_exp_power;
    *(double *)mppt_power_all += cab->cab_ctrl.mppt_exp_power;

    return 0;
}

// 动态增容 单柜PCS功率处理回调
int DCE_charge_pcs_mppt_exp_power(cabinet_inside_t *cab, void *arg)
{
 
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_set ? cab->cab_ctrl.pcs_discharge_max_set : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_set ? cab->cab_ctrl.pcs_charge_max_set : cab->cab_ctrl.pcs_exp_power;   

    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_actual ? cab->cab_ctrl.pcs_discharge_max_actual : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_actual ? cab->cab_ctrl.pcs_charge_max_actual : cab->cab_ctrl.pcs_exp_power;   


   double charge_max = microgrid_ctrl.pcs_exp_power * cab->cab_cfg.scale;      // 总最大充电功率分配给该柜
    double set_charge_power = charge_max < cab->cab_ctrl.bms_exp_power ? cab->cab_ctrl.bms_exp_power : charge_max;  // 该柜基于BMS_exp决定充电最大功率
    
    cab->cab_ctrl.mppt_exp_power = -cab->cab_ctrl.bms_exp_power;    
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.bms_exp_power + (cab->cab_data.mppt_out_power < 0 ? 0 : cab->cab_data.mppt_out_power);
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < set_charge_power ? set_charge_power : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > 0 ? 0 : cab->cab_ctrl.pcs_exp_power;
    *(double *)arg += cab->cab_ctrl.pcs_exp_power;
    UD_log_sprintf(micro_log, "\n cab[%s] 柜期望功率: %lf", cab->no, microgrid_ctrl.pcs_exp_power);

    return 0;
}

/**
 * @description: 动态增容放电回调
 * @param {cabinet_inside_t} *cab
 * @param {void} *arg
 * @return {*}
 */
int DCE_discharge_mppt_exp_power(cabinet_inside_t *cab, void *arg)
{
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_set ? cab->cab_ctrl.pcs_discharge_max_set : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_set ? cab->cab_ctrl.pcs_charge_max_set : cab->cab_ctrl.pcs_exp_power;   

    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_actual ? cab->cab_ctrl.pcs_discharge_max_actual : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_actual ? cab->cab_ctrl.pcs_charge_max_actual : cab->cab_ctrl.pcs_exp_power;   


    cab->cab_ctrl.mppt_exp_power = -cab->cab_ctrl.bms_exp_power + cab->cab_ctrl.pcs_exp_power;
    UD_log_sprintf(micro_log, "\ncab[%s] 柜总光伏期望功率: %lf", cab->no, cab->cab_ctrl.mppt_exp_power);

    return 0;
}

/**
 * @description: 动态增容静置回调
 * @param {cabinet_inside_t} *cab
 * @param {void} *arg
 * @return {*}
 */
int DCE_stewing_mppt_exp_power(cabinet_inside_t *cab, void *arg)
{
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_set ? cab->cab_ctrl.pcs_discharge_max_set : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_set ? cab->cab_ctrl.pcs_charge_max_set : cab->cab_ctrl.pcs_exp_power;   

    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > cab->cab_ctrl.pcs_discharge_max_actual ? cab->cab_ctrl.pcs_discharge_max_actual : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_actual ? cab->cab_ctrl.pcs_charge_max_actual : cab->cab_ctrl.pcs_exp_power;   


    if(cab->cab_ctrl.bms_exp_power < 0)
    {
        cab->cab_ctrl.mppt_exp_power = -cab->cab_ctrl.bms_exp_power;
        cab->cab_ctrl.pcs_exp_power = 0;
    }
    else if(cab->cab_ctrl.bms_exp_power > 0)
    {
        cab->cab_ctrl.mppt_exp_power = 0; // 弃光均衡 pcs按原有期望输出
    }
    else
    {
        cab->cab_ctrl.mppt_exp_power = cab->cab_ctrl.pcs_exp_power; // 期望功率赋给mppt
        cab->cab_ctrl.pcs_exp_power = cab->cab_data.mppt_out_power; // 实际下发来自pcs
    }

    *(double *)arg += cab->cab_ctrl.pcs_exp_power;
    UD_log_sprintf(micro_log, "\n cab[%s] 柜期望功率: %lf   柜总光伏期望功率: %lf", cab->no, microgrid_ctrl.pcs_exp_power, cab->cab_ctrl.mppt_exp_power);
    BUSINESS_LOG(LOG_NOTICE, DC_ID_0005, cab->no, "[直流耦合]: cab[%s] 柜期望功率: %lf   柜总光伏期望功率: %lf", cab->no, microgrid_ctrl.pcs_exp_power, cab->cab_ctrl.mppt_exp_power);

    return 0;
}


/**
 * @description: 对单个目标柜的PCS期望功率和MPPT的期望功率设置逻辑（仅限制于削峰填谷-充电逻辑、光储备电逻辑 属业务逻辑封装 勿随意调用）
 * @param {cabinet_inside_t} *cab
 * @return {*}
 */
int peakLoadShifting_pcs_mppt_exp_power(cabinet_inside_t *cab, void *arg)
{
    double BMS_power = cab->cab_ctrl.bms_exp_power;
        /**///ems_syslog(LOG_ERR,"连续log标志:SOC = %lf", microgrid_data.SOC_average);
        /**///ems_syslog(LOG_ERR,"连续log标志:pcs_exp_power = %lf", cab->cab_ctrl.pcs_exp_power);
    
    UD_log_sprintf(micro_log, "\n{单柜业务逻辑");
    
    if(BMS_power < 0)
    {
        /**///ems_syslog(LOG_ERR,"连续log标志:BMS充电");
        
        cab->cab_ctrl.mppt_exp_power = -BMS_power;

        cab->cab_ctrl.pcs_exp_power = -((-BMS_power) - cab->cab_data.mppt_out_power);        // PCS 补充剩余部分 尽快将

        /*限幅*/
        cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > 0 ? 0 : cab->cab_ctrl.pcs_exp_power;
        UD_log_sprintf(micro_log, "\n<BMS期望充电\n策略逻辑: 光伏期望功率= %lf(BMS最大充电功率)\nPCS期望功率= %lf(BMS最大充电功率) - %lf(光伏实际输出)", cab->cab_ctrl.mppt_exp_power, -BMS_power, cab->cab_ctrl.pcs_exp_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0006, cab->no, "[直流耦合]: cab[%s] BMS期望充电，策略逻辑: 光伏期望功率= %lf(BMS最大充电功率) PCS期望功率= %lf(BMS最大充电功率) - %lf(光伏实际输出)", cab->no, cab->cab_ctrl.mppt_exp_power, -BMS_power, cab->cab_ctrl.pcs_exp_power);
        cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < cab->cab_ctrl.pcs_charge_max_set ? cab->cab_ctrl.pcs_charge_max_set : cab->cab_ctrl.pcs_exp_power;
        UD_log_sprintf(micro_log, "\n充电限制: %lf PCS期望功率限制后: %lf  >\n", cab->cab_ctrl.pcs_charge_max_set, cab->cab_ctrl.pcs_exp_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0007, cab->no, "[直流耦合]: cab[%s] 充电限制: %lf PCS期望功率限制后: %lf: %lf", cab->no, cab->cab_ctrl.pcs_charge_max_set, cab->cab_ctrl.pcs_exp_power);
    }
    // BMS过充 释放
    else if(BMS_power > 0)      // PCS放电
    {
        /**///ems_syslog(LOG_ERR,"连续log标志:BMS来放电");

        cab->cab_ctrl.pcs_discharge_max_set = cab->cab_ctrl.pcs_discharge_max_actual;
        cab->cab_ctrl.pcs_charge_max_set = 0;
        cab->cab_ctrl.mppt_exp_power = 0;     // 让BMS负荷所有功率
        UD_log_sprintf(micro_log, "\n<BMS期望放电\n策略逻辑: 光伏期望功率写0\nPCS期望功率: %lf>\n", cab->cab_ctrl.pcs_exp_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0006, cab->no, "[直流耦合]: cab[%s] BMS期望放电 策略逻辑: 光伏期望功率写0 PCS期望功率: %lf", cab->no, cab->cab_ctrl.pcs_exp_power);
    }
    // BMS 逻辑静置 PCS输出 = 光伏实际输出 光伏门限输出为PCS期望功率
    else                        // PCS放电
    {
    
        cab->cab_ctrl.mppt_exp_power =  (cab->cab_ctrl.pcs_exp_power > cab->cab_cfg.mppt_power_max) ? cab->cab_cfg.mppt_power_max : cab->cab_ctrl.pcs_exp_power;        //限幅
        if(microgrid_cfg.en_photovoltaic)
            cab->cab_ctrl.pcs_exp_power = cab->cab_data.mppt_out_power;
        else
            cab->cab_ctrl.pcs_exp_power = 0;
        
        UD_log_sprintf(micro_log, "\n<BMS静置\n策略逻辑: 光伏门限期望功率: %lf\nPCS期望功率=%lf(光伏实际输出功率)>\n", cab->cab_ctrl.mppt_exp_power, cab->cab_ctrl.pcs_exp_power );
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0006, cab->no, "[直流耦合]: cab[%s] BMS静置 策略逻辑: 光伏门限期望功率: %lf PCS期望功率=%lf(光伏实际输出功率): %lf", cab->no, cab->cab_ctrl.pcs_exp_power);

    }
    if(1 != microgrid_cfg.en_photovoltaic)
    {
        cab->cab_ctrl.mppt_exp_power = 0;
    }
    *(double *)arg += cab->cab_ctrl.mppt_exp_power;
    UD_log_sprintf(micro_log, "}\n");

    return 0;
}


/**
 * @description: ems_plan的静置逻辑，静置逻辑下 BMS仍然受光伏充电，但自身不参与放电（未过充情况下）
 * @param {cabinet_inside_t} *cab
 * @param {void} *arg
 * @return {*}
 */
int peakLoadShifting_stewing(cabinet_inside_t *cab, void *arg)
{
    double exp_power = *(double *)arg * cab->cab_cfg.scale;
    double BMS_power = cab->cab_ctrl.bms_exp_power;
    UD_log_sprintf(micro_log, "\n{单柜业务逻辑");
    if(microgrid_cfg.en_photovoltaic == 0 || cab->mppt.num <= 0)    // 没光伏不管
    {
        UD_log_sprintf(micro_log, "\n<未使能光伏 or 光伏设备为[%d] PCS期望功率设0>\n", cab->mppt.num);
        UD_log_sprintf(micro_log, "}\n");

        cab->cab_ctrl.pcs_exp_power = 0;
        return 0;
    }
    cab->cab_ctrl.pcs_discharge_max_set = microgrid_ctrl.discharge_max_set * cab->cab_cfg.scale;
    cab->cab_ctrl.pcs_charge_max_set = microgrid_ctrl.charge_max_set * cab->cab_cfg.scale;
    UD_log_sprintf(micro_log, "\n<业务逻辑: 基于上步计算PCS期望功率: %lf, BMS期望功率: %lf", exp_power, BMS_power);
    
    if(BMS_power > 0)
    {
        UD_log_sprintf(micro_log, "SOC超过归中算法阈值 期望放电, 设置MPPT门限为0 放电功率期望由BMS放出");

        cab->cab_ctrl.mppt_exp_power = 0;
        cab->cab_ctrl.pcs_exp_power = exp_power;
    }
    else 
    {

        cab->cab_ctrl.mppt_exp_power = exp_power - BMS_power;
        cab->cab_ctrl.mppt_exp_power = cab->cab_ctrl.mppt_exp_power < 0 ? 0 : cab->cab_ctrl.mppt_exp_power; 
        cab->cab_ctrl.pcs_exp_power = cab->cab_data.mppt_out_power + BMS_power;
        UD_log_sprintf(micro_log, "设置MPPT门限为: %lf = %lf(PCS期望功率) - %lf(BMS期望功率)", cab->cab_ctrl.mppt_exp_power,exp_power, BMS_power);
    }
    
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power > exp_power ? exp_power : cab->cab_ctrl.pcs_exp_power;
    cab->cab_ctrl.pcs_exp_power = cab->cab_ctrl.pcs_exp_power < 0 ? 0 : cab->cab_ctrl.pcs_exp_power; 
    UD_log_sprintf(micro_log, "基于实际MPPT输出功率: %lf 设置PCS 实际期望功率: %lf>\n",  cab->cab_data.mppt_out_power, cab->cab_ctrl.pcs_exp_power);
    UD_log_sprintf(micro_log, "}\n");

    return 0;
}
 
/**
 * @description: 削峰填谷
 * @param {double} *value_set: double[2] 的指针 获取功率
 * @return {*}
 */
static void peakLoadShifting()
{
    double tmp_charge_power_max = 0;
    double PCS_power = 0, charge_exp_max = 0, discharg_exp_max = 0;
    double BMS_power = 0;
    double MPPT_power = 0; 
    static enum ENERGY_DIRECTION status_last = 0; // 用于记录状态变化 若状态切换需要对相关数据回收

    if (microgrid_ctrl.plan_statu != status_last)
    {
        traverse_cab_dev_func(pcs_limit_reset); // 重置PCS充放电门限
        antiReflux(0, 0, 0, 0, 0, 0, 1);
        pcs_stop();
        mppt_stop();

        // 从放电切换至充电
        if (microgrid_ctrl.plan_statu == DISCHARGE_DIRECTION && status_last == CHARGE_DIRECTION)
        {
        }

        if (microgrid_ctrl.plan_statu ==  CHARGE_DIRECTION&& status_last == DISCHARGE_DIRECTION)
        {
        }

    }
    /**////**///ems_syslog(LOG_ERR,"GRID_data.GRID_POWER = %lf, PCS_data.out_power = %lf", Micro_data_buf->GRID_data.GRID_POWER, Micro_data_buf->PCS_data.out_power_get);
    /**////**///ems_syslog(LOG_ERR,"plan_statu = %d", microgrid_cfg.plan_statu);
    /**////**///ems_syslog(LOG_ERR,"ControlMode = %d", microgrid_ctrl.ControlMode);
    /**///ems_syslog(LOG_ERR,"连续log标志:削峰填谷策略");
    UD_log_sprintf(micro_log, "\n当前计划:[%d]  %d:放电 %d:充电 %d:静置\n", microgrid_ctrl.plan_statu, DISCHARGE_DIRECTION, CHARGE_DIRECTION, ENERGY_DEFAULT);
    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 当前计划:[%d]  %d:放电 %d:充电 %d:静置", microgrid_ctrl.plan_statu, DISCHARGE_DIRECTION, CHARGE_DIRECTION, ENERGY_DEFAULT);
    switch(microgrid_ctrl.plan_statu) 
    {
        case DISCHARGE_DIRECTION/*放电*/:
        /**///ems_syslog(LOG_ERR,"连续log标志:放电模式");
            // BMS SOC上下限保护
            cabinet_bms_protect();
           
            // BMS_protect_to_ctrl_PCS(Micro_data_buf->BMS_data.SOC, microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_combin,  microgrid_ctrl.SOCminReturnDiff, microgrid_ctrl.SOCminReturnDiff, microgrid_cfg.plan_statu); 
            // 得到PCS需求功率
            if(microgrid_ctrl.EnTraceLoad)
            {
                UD_log_sprintf(micro_log, "\n<负荷跟踪模式>\n");
                double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;

                if(microgrid_ctrl.en_anti_reflux)
                {
                    grid -= microgrid_ctrl.anti_reflux;
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-放电策略:使能负荷跟踪与防逆流");
                    UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");

                }
                else 
                {
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-放电策略:使能负荷跟踪");
                    UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
                }
                PCS_power = antiReflux(
                    grid - (grid + microgrid_data.pcs_power) * microgrid_ctrl.TraceLoad , 
                    1,  
                    1,
                    microgrid_ctrl.plan_set_power, 
                    0, 
                    microgrid_data.pcs_power, 
                    0);
                UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
                BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);

            }
            else if(microgrid_ctrl.en_anti_reflux)
            {
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-放电策略:使能防逆流");
                
                UD_log_sprintf(micro_log, "\n<使能防逆流>\n");
                PCS_power = antiReflux(
                    dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
                    microgrid_ctrl.anti_reflux,  
                    1, 
                    microgrid_ctrl.plan_set_power, 
                    0, 
                    microgrid_data.pcs_power, 
                    0);
                
                PCS_power = PCS_power > microgrid_ctrl.plan_set_power ? microgrid_ctrl.plan_set_power :PCS_power;
                UD_log_sprintf(micro_log, "\n<防逆流算法期望功率: %lf>\n", PCS_power);
                BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 防逆流算法期望功率: %lf", PCS_power);
            }
            else
            {
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-放电策略:未使能负荷跟踪 将按照策略:%f 下发", PCS_power);
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-放电策略:未使能防逆流 将按照策略:%f 下发", PCS_power);

                PCS_power = microgrid_ctrl.plan_set_power;  // plan约束

                if (PCS_power > 0)
                    PCS_power = (PCS_power > microgrid_ctrl.dischargeMaxPower ? microgrid_ctrl.dischargeMaxPower : PCS_power);
                if(PCS_power < 0)
                    PCS_power = (PCS_power < microgrid_ctrl.chargeMaxPower ? microgrid_ctrl.chargeMaxPower : PCS_power);

                UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
                BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);
            }
            /**///ems_syslog(LOG_ERR,"PCS期望功率:%lf", PCS_power);

            microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
            
            /**////**/ems_syslog(LOG_ERR,"滤波后得到预设功率 PCS_out_power = %lf", PCS_out_power);

            // 得到BMS需求功率
            BMS_power = cabinet_bms_centering();
            UD_log_sprintf(micro_log, "\n<BMS期望功率: %lf>\n", BMS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: BMS期望功率: %lf", BMS_power);

            // BMS_power = homingAlgorithmSOC(microgrid_ctrl.SOC_min_combin, microgrid_ctrl.SOC_max_combin, microgrid_ctrl.SOCmaxReturnDiff, Micro_data_buf->PCS_data.out_power_get, 1); // 归中算法 下方逻辑将随从调整
            /**////**/ems_syslog(LOG_ERR,"BMS期望功率 = %lf", BMS_power);

            /**////**/ems_syslog(LOG_ERR,"放电状态");
            /*光伏 PCS 动态算法层*/
            /*END*/
            // 得到光伏需求功率
            if(microgrid_cfg.en_photovoltaic)
            {
                Multi_cabinet_power_distribution(PCS_power);
            }
            else 
            {
                UD_log_sprintf(micro_log, "\n未使能光伏动态调度，默认PCS功率均分开环调度下发");
                traverse_cab_dev_func(cabinet_pcs_exp_power_set);
            }
            break;
        case CHARGE_DIRECTION/*充电*/:
        
            
            tmp_charge_power_max = -fabs(microgrid_ctrl.plan_set_power < microgrid_ctrl.chargeMaxPower ? microgrid_ctrl.chargeMaxPower : microgrid_ctrl.plan_set_power);
            
            BMS_power = cabinet_bms_centering();
            {
                UD_log_sprintf(micro_log, "\n<BMS 期望充电>\n");

                if (microgrid_ctrl.EnProtectTransf == 1){
                    UD_log_sprintf(micro_log, "\n<使能变压器保护>\n");


                    double _Pmlmax = microgrid_ctrl.Pmlmax * ((double)microgrid_ctrl.K1 / 100.0);
                    PCS_power = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限
                        microgrid_data.grid_appower, 
                        _Pmlmax + microgrid_ctrl.PmlmaxDiff,
                        1, 
                        0/* fabs(microgrid_ctrl.discharge_max_set)*/, 
                        tmp_charge_power_max,
                        microgrid_data.pcs_power, 
                        _Pmlmax,
                        0);
                    UD_log_sprintf(micro_log, "\n<变压器保护算法期望功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 变压器保护算法期望功率: %lf", PCS_power);
                }
                else if(g_usercfg_variant.EnProtectTransf == 2) // 最大需量
                {
                    double max_demand = microgrid_ctrl.MaxDemand;    // 门限
                    UD_log_sprintf(micro_log, "\n<使能最大需量>\n");
                    
                    max_demand = microgrid_ctrl.Pmlmax  < max_demand ? microgrid_ctrl.Pmlmax : max_demand;
                    
                    double max_demand_limit = max_demand - microgrid_ctrl.PmlmaxDiff;
                    max_demand_limit = max_demand_limit > 0 ? max_demand_limit : 0;
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_DEMAND, NULL, "计划策略-充电策略:使能需量保护");

                    PCS_power = xl_antiReflux(
                        microgrid_data.grid_power, 
                        max_demand, 
                        1, 
                        0/*系统最大放电功率*/, 
                        tmp_charge_power_max, 
                        microgrid_data.pcs_power, 
                        max_demand_limit, 
                        0);
                    UD_log_sprintf(micro_log, "\n<需量算法期望功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 需量算法期望功率: %lf", PCS_power);
                }
                else {
                    UD_log_sprintf(micro_log, "\n<无充电保护 将按照系统最大充电功率: %lf>\n", tmp_charge_power_max);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 无充电保护 将按照系统最大充电功率: %lf", tmp_charge_power_max);
                    PCS_power = tmp_charge_power_max;
                }
                

                if(microgrid_ctrl.EnProtectTrasLV == 1)
                {
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_LV_TRAN, NULL, "计划策略-充电策略:使能低压侧变压器保护");

                    double _Pmlmax = microgrid_ctrl.Pmlmax * microgrid_ctrl.k4 / 100.0;
                    UD_log_sprintf(micro_log, "\n<使能低压侧变压器保护>\n" );

                    double power_tmp = xl_LV_antiReflux(microgrid_data.grid_appower, 
                        _Pmlmax + microgrid_ctrl.PmlmaxDiff, 
                        1, 
                        0, 
                        tmp_charge_power_max, 
                        microgrid_data.pcs_power,
                         _Pmlmax,
                        0);
                    UD_log_sprintf(micro_log, "\n<低压侧变压器保护算法期望功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 低压侧变压器算法期望功率: %lf", PCS_power);
                                        
                    PCS_power = PCS_power < power_tmp ? power_tmp : PCS_power;  // 按负充正放，此处按最小充电功率来
                }
                else 
                {
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_LV_TRAN, NULL, "计划策略-充电策略:失能低压侧变压器保护");
                }
                UD_log_sprintf(micro_log, "\n<期望功率: %lf>\n", PCS_power);
                
                // traverse_cab_dev_func_arg(set_pcs_ctrl_chargepower, &PCS_power);

                charge_exp_max = PCS_power;  

            }
            {
                UD_log_sprintf(micro_log, "\n<BMS 充满, 将尝试将光伏功率放出>\n");
            
                if(microgrid_ctrl.EnTraceLoad)
                {
                    UD_log_sprintf(micro_log, "\n<负荷跟踪模式>\n");

                    double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
                    if(microgrid_ctrl.en_anti_reflux)
                    {
                        grid -= microgrid_ctrl.anti_reflux;
                        UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
                        BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-充电策略:使能负荷跟踪与防逆流");

                    }
                    else 
                    {
                        UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
                        BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-充电策略:使能负荷跟踪");
                    }
                    
                    PCS_power = antiReflux(
                        grid - (grid + microgrid_data.pcs_power) * microgrid_ctrl.TraceLoad, 
                        1,  
                        1,
                        microgrid_ctrl.dischargeMaxPower, 
                        0, 
                        microgrid_data.pcs_power, 
                        0);
                    UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);

                }
                else if(microgrid_ctrl.en_anti_reflux)  // 防逆流开启与否  
                {
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-充电策略:使能防逆流");
                    UD_log_sprintf(micro_log, "\n<使能防逆流>\n");
                    PCS_power = antiReflux(
                        dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
                        microgrid_ctrl.anti_reflux,  
                        1, 
                        microgrid_ctrl.discharge_max_set, 
                        0, 
                        microgrid_data.pcs_power, 
                        0);
                    UD_log_sprintf(micro_log, "\n<防逆流算法期望功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 防逆流算法期望功率: %lf", PCS_power);
                }
                else
                {
                    PCS_power = microgrid_ctrl.dischargeMaxPower;   // 按照最大放电功率作为放电期望
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-充电策略:未使能负荷跟踪 将按照策略:%f 作为光伏期望", PCS_power);
                    BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-充电策略:未使能防逆流 将按照策略:%f 作为光伏期望", PCS_power);

                    UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
                    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);
                }
                discharg_exp_max = PCS_power;
                
            }
            /**////**/ems_syslog(LOG_ERR,"PCS期望功率:%lf", PCS_power);
        /**///ems_syslog(LOG_ERR,"连续log标志:PCS期望功率:%lf", PCS_power);
            microgrid_ctrl.pcs_exp_power = charge_exp_max;   // 刷新期望功率

            if(microgrid_cfg.en_photovoltaic)
            {
                Multi_cabinet_power_distribution_charge(discharg_exp_max, charge_exp_max);
            }
            else 
            {
                UD_log_sprintf(micro_log, "\n未使能光伏动态调度，默认PCS功率均分开环调度下发");
                traverse_cab_dev_func(cabinet_pcs_exp_power_set);
            }
            // microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
            // traverse_cab_dev_func(cabinet_pcs_exp_power_set);   // 先分发期望功率 随后处理实际下发功率
            // // double power_charge_cab = microgrid_ctrl.plan_set_power / dev_info_all.cabinet_info.num;
            // // traverse_cab_dev_func_arg(set_cab_charge_max, &power_charge_cab);
            // MPPT_power = 0;
            // traverse_cab_dev_func_arg(peakLoadShifting_pcs_mppt_exp_power, &MPPT_power);
        /**///ems_syslog(LOG_ERR,"连续log标志:MPPT_power:%lf", MPPT_power);


            /*END*/

            break;
        case ENERGY_DEFAULT/*静置*/:
        BMS_power = cabinet_bms_centering();
        
        tmp_charge_power_max = microgrid_ctrl.chargeMaxPower ;
        if(microgrid_ctrl.EnTraceLoad)
        {
            UD_log_sprintf(micro_log, "\n<负荷跟踪模式>\n");

            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_TRAN, NULL, "计划策略-静置策略:使能变压器保护");
            double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
            if(microgrid_ctrl.en_anti_reflux)
            {
                grid -= microgrid_ctrl.anti_reflux;
                UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-静置策略:使能负荷跟踪与防逆流");

            }
            else 
            {
                UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-静置策略:使能负荷跟踪");
            }
            PCS_power = antiReflux(
                grid - (grid + microgrid_data.pcs_power) * microgrid_ctrl.TraceLoad, 
                1,  
                1,
                microgrid_ctrl.dischargeMaxPower, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);
        }
        else if(microgrid_ctrl.en_anti_reflux)  // 防逆流开启与否  
        {
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-静置策略:使能防逆流");
            UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
            PCS_power = antiReflux(
                dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
                microgrid_ctrl.anti_reflux,  
                1, 
                microgrid_ctrl.discharge_max_set, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, "\n<防逆流算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 防逆流算法期望功率: %lf", PCS_power);
        }
        else
        {
            PCS_power = microgrid_ctrl.dischargeMaxPower;   // 按照最大放电功率作为放电期望
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "计划策略-静置策略:未使能负荷跟踪 将按照策略:%f 作为光伏期望", PCS_power);
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "计划策略-静置策略:未使能防逆流 将按照策略:%f 作为光伏期望", PCS_power);
            UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);
        }
        if(microgrid_cfg.en_photovoltaic)
        {
            Multi_cabinet_power_distribution_stewing(PCS_power);
        }
        else 
        {
            UD_log_sprintf(micro_log, "\n未使能光伏动态调度，默认PCS功率均分开环调度下发");
            traverse_cab_dev_func(cabinet_pcs_exp_power_set);
        }

            break;
        default:
            UD_log_sprintf(micro_log, "\n<未注册策略!>\n");
            stop_power_allocation();
            break;
    }
    status_last = microgrid_ctrl.plan_statu;
    PCS_set_power(PCS_power, 0);
    MPPT_set_power(MPPT_power, 0);

}


/**
 * @description: 光伏消纳
 * @param {double} *value_set: double[2] 的指针 获取功率
 * @return {*}
 */
static void PhotovoltaicAbsorption()
{
    /*直接设置plan模式为放电模式*/
    microgrid_ctrl.plan_statu = DISCHARGE_DIRECTION;
    if(0 == microgrid_cfg.en_photovoltaic)   
    {
        /**///ems_syslog(LOG_ERR,"en_photovoltaic is 0! return PhotovoltaicAbsorption set_power = 0");
        // stop_power_allocation();
        return;
    }
    double PCS_power = 0; 
    double BMS_power = 0; 
    double MPPT_power = 0;
    cabinet_bms_protect();

    // 得到PCS需求功率
    if(microgrid_ctrl.EnTraceLoad)
    {
        UD_log_sprintf(micro_log, "\n<负荷跟踪模式>\n");
        double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
        if(microgrid_ctrl.en_anti_reflux)
        {
            grid -= microgrid_ctrl.anti_reflux;
            UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "自发自用:使能负荷跟踪与防逆流");

        }
        else 
        {
            UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "自发自用:使能负荷跟踪");
        }
        PCS_power = antiReflux(
            grid - (grid + microgrid_data.pcs_power) * microgrid_ctrl.TraceLoad , 
            1,  
            1,
            microgrid_ctrl.dischargeMaxPower, 
            0, 
            microgrid_data.pcs_power, 
            0);
        UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);

    }
    else if(microgrid_ctrl.en_anti_reflux)
    {
        
        BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "自发自用:使能防逆流");

        PCS_power = antiReflux(
            dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
            microgrid_ctrl.anti_reflux,  
            1, 
            microgrid_ctrl.dischargeMaxPower, 
            0, 
            microgrid_data.pcs_power, 
            0);
        UD_log_sprintf(micro_log, " \n<使能防逆流,算法推导PCS期望功率:%lf>\n", PCS_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 使能防逆流,算法推导PCS期望功率:%lf", PCS_power);
    }
    else
    {
        PCS_power = microgrid_ctrl.dischargeMaxPower;  // plan约束
        BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "自发自用:未使能负荷跟踪 将按照策略:%f 作为光伏期望", PCS_power);
        BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "自发自用:未使能防逆流 将按照策略:%f 作为光伏期望", PCS_power);
        UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);

    }
    microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
    BMS_power = cabinet_bms_centering();
    UD_log_sprintf(micro_log, " \n<BMS 期望功率:%lf>\n", BMS_power);
    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: BMS 期望功率:%lf", BMS_power);
    
    if(microgrid_cfg.en_photovoltaic)
    {
        Multi_cabinet_power_distribution(PCS_power);
    }
    else {
        microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
        traverse_cab_dev_func(cabinet_pcs_exp_power_set); 
    }
    MPPT_power =   PCS_power - BMS_power;
    PCS_set_power(PCS_power, 0);
    MPPT_set_power(MPPT_power, 0);
}

/**
 * @description: 应急备电
 * @return {*}
 */
void Emergency_backup_power()
{
    double BMS_power = 0,PCS_power = 0,MPPT_power = 0,tmp_charge_power_max = 0,charge_exp_max = 0, discharg_exp_max = 0;

    tmp_charge_power_max = microgrid_ctrl.chargeMaxPower ;
    
    BMS_power = cabinet_bms_centering();
    ems_syslog(LOG_ERR, "BMS_power:%lf", BMS_power);
    {
        UD_log_sprintf(micro_log, "\n<BMS 期望充电>\n");
        if (microgrid_ctrl.EnProtectTransf == 1){
            UD_log_sprintf(micro_log, "\n<使能变压器保护>\n");

            double _Pmlmax = microgrid_ctrl.Pmlmax * ((double)microgrid_ctrl.K1 / 100.0);
            PCS_power = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限
                microgrid_data.grid_appower, 
                _Pmlmax + microgrid_ctrl.PmlmaxDiff,
                1, 
                0/* fabs(microgrid_ctrl.discharge_max_set)*/, 
                tmp_charge_power_max,
                microgrid_data.pcs_power, 
                _Pmlmax,
                0);
            UD_log_sprintf(micro_log, "\n<变压器保护算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 变压器保护算法期望功率: %lf", PCS_power);
        }
        else if(g_usercfg_variant.EnProtectTransf == 2) // 最大需量
        {
            double max_demand = microgrid_ctrl.MaxDemand;    // 门限
            UD_log_sprintf(micro_log, "\n<使能最大需量>\n");
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_DEMAND, NULL, "应急备电:使能需量保护");
            max_demand = microgrid_ctrl.Pmlmax  < max_demand ? microgrid_ctrl.Pmlmax : max_demand;
            
            double max_demand_limit = max_demand - microgrid_ctrl.PmlmaxDiff;
            max_demand_limit = max_demand_limit > 0 ? max_demand_limit : 0;

            PCS_power = xl_antiReflux(
                microgrid_data.grid_power, 
                max_demand, 
                1, 
                0/*系统最大放电功率*/, 
                tmp_charge_power_max, 
                microgrid_data.pcs_power, 
                max_demand_limit, 
                0);
            UD_log_sprintf(micro_log, "\n<需量保护算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 需量算法期望功率: %lf", PCS_power);
        }
        else {
            UD_log_sprintf(micro_log, "\n<无充电保护 将按照系统最大充电功率: %lf>\n", tmp_charge_power_max);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 无充电保护 将按照系统最大充电功率: %lf", tmp_charge_power_max);
            PCS_power = tmp_charge_power_max;
        }

        if(microgrid_ctrl.EnProtectTrasLV == 1)
        {
            double _Pmlmax = microgrid_ctrl.Pmlmax * microgrid_ctrl.k4 / 100.0;
            UD_log_sprintf(micro_log, "\n<使能低压侧变压器保护>\n" );
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_LV_TRAN, NULL, "应急备电:使能低压侧变压器保护");
            double power_tmp = xl_LV_antiReflux(microgrid_data.grid_appower, 
                _Pmlmax + microgrid_ctrl.PmlmaxDiff, 
                1, 
                0, 
                tmp_charge_power_max, 
                microgrid_data.pcs_power,
                    _Pmlmax,
                0);
            
            PCS_power = PCS_power < power_tmp ? power_tmp : PCS_power;  // 按负充正放，此处按最小充电功率来
        }
        else 
        {
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_XL_ANTIREFLUX_LV_TRAN, NULL, "应急备电:失能低压侧变压器保护");
        }
        UD_log_sprintf(micro_log, "\n<期望功率: %lf>\n", PCS_power);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 期望功率: %lf", PCS_power);
        charge_exp_max = PCS_power;
    }
    {
        if(microgrid_ctrl.EnTraceLoad)
        {
            double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
            UD_log_sprintf(micro_log, "\n使能负荷跟踪");

            if(microgrid_ctrl.en_anti_reflux)
            {
                grid -= microgrid_ctrl.anti_reflux;
                UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "应急备电:使能负荷跟踪与防逆流");

            }
            else 
            {
                UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "应急备电:使能负荷跟踪");
            }
            PCS_power = antiReflux(
                grid - (grid + microgrid_data.pcs_power) *  microgrid_ctrl.TraceLoad , 
                1,  
                1,
                microgrid_ctrl.dischargeMaxPower, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);
        }
        else if(microgrid_ctrl.en_anti_reflux){  // 防逆流开启与否  
            PCS_power = antiReflux(
                dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
                microgrid_ctrl.anti_reflux,  
                1, 
                microgrid_ctrl.discharge_max_set, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, " \n<使能防逆流,算法推导PCS期望功率:%lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 使能防逆流,算法推导PCS期望功率:%lf", PCS_power);
        }
        else{        
            PCS_power = microgrid_ctrl.dischargeMaxPower;   // 按照最大放电功率作为放电期望
            UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);    
        }
        discharg_exp_max = PCS_power;
    }
    /**////**/ems_syslog(LOG_ERR,"PCS期望功率:%lf", PCS_power);
/**///ems_syslog(LOG_ERR,"连续log标志:PCS期望功率:%lf", PCS_power);

    microgrid_ctrl.pcs_exp_power = charge_exp_max;   // 刷新期望功率
    UD_log_sprintf(micro_log, "\n 负载端总期望 %lf", microgrid_ctrl.pcs_exp_power);
    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负载端总期望 %lf", microgrid_ctrl.pcs_exp_power);

    if(microgrid_cfg.en_photovoltaic)
    {
        Multi_cabinet_power_distribution_charge(discharg_exp_max, charge_exp_max);
    }
    else 
    {
        traverse_cab_dev_func(cabinet_pcs_exp_power_set);
    }
    // double power_charge_cab = microgrid_ctrl.plan_set_power / dev_info_all.cabinet_info.num;
    // traverse_cab_dev_func_arg(set_cab_charge_max, &power_charge_cab);

    // MPPT_power = 0;
    // traverse_cab_dev_func_arg(peakLoadShifting_pcs_mppt_exp_power, &MPPT_power);
    
    PCS_set_power(PCS_power, 0);
    MPPT_set_power(MPPT_power, 0);

    /*END*/
}



/**
 * @description: 把PCS实际输出作为该柜的PCS期望功率 便于后续mppt功率计算
 * @param {cabinet_inside_t} *cab
 * @return {*}
 */
int off_grid_set_pcs_power(cabinet_inside_t *cab)
{
    cab->cab_ctrl.pcs_exp_power = cab->cab_data.pcs_output_power;
    return 0;
}

/**
 * @description: 离网模式
 * @param {double} *power_all_devs
 * @return {*}
 */
static void off_grid_mode()
{
    double BMS_power = cabinet_bms_centering();// 得到BMS期望功率
    microgrid_ctrl.bms_exp_power = BMS_power;

    microgrid_ctrl.pcs_exp_power = microgrid_data.pcs_power;   // 将PCS实际输出功率作为PCS的期望功率便于后续计算
    microgrid_ctrl.mppt_exp_power = -BMS_power + microgrid_ctrl.pcs_exp_power;
    microgrid_ctrl.mppt_exp_power = microgrid_ctrl.mppt_exp_power < 0 ? 0 : microgrid_ctrl.mppt_exp_power; 
    traverse_cab_dev_func(off_grid_set_pcs_power);  // 针对单个柜 PCS 期望功率刷新
    traverse_cab_dev_func(off_grid_mppt_exp_power_func);  // 根据BMS和PCS期望功率可得到 针对单个柜 mppt 期望功率 并刷新
    MPPT_set_power(microgrid_ctrl.mppt_exp_power, 0);
}

int is_time_in_range(int start_h, int start_m, int start_s, int end_h, int end_m, int end_s) {
    // 获取当前时间
    time_t now = time(NULL);

    struct tm target_time = {};  
    localtime_r(&now, &target_time);
    struct tm *tm_now = &target_time;
    int current_secs = tm_now->tm_hour * 3600 + tm_now->tm_min * 60 + tm_now->tm_sec;

    // 计算开始和结束时间的总秒数
    int start_total = start_h * 3600 + start_m * 60 + start_s;
    int end_total = end_h * 3600 + end_m * 60 + end_s;

    // 判断当前时间是否在区间内
    return (current_secs >= start_total && current_secs <= end_total) ? 1 : 0;
}




/**
 * @description: 动态增容
 * @return {*}
 */
int Dynamic_capacity_expansion()
{
    double PCS_power = 0;
    double MPPT_power = 0;
    int time_charge_en = is_time_in_range(
        microgrid_ctrl.DemandStartHour,
        microgrid_ctrl.DemandStartMin,
        0,
        microgrid_ctrl.DemandEndHour,
        microgrid_ctrl.DemandEndMin,
        0
    );
    
    double cur_power_HV = 0;
    double cur_power_LV = 0;

    /*对等设计暂时不做处理*/
    /*double k_val = 0;
    if(g_usercfg_variant.K3 == 0)
        k_val = 0;
    else
    {
        float ex_total_pcs = 0;
        int ex_total_k3 = 0;
        get_extern_agv_pcs_val(&ex_total_pcs, &ex_total_k3);

        k_val = (double)g_usercfg_variant.K3 / (ex_total_k3 + g_usercfg_variant.K3);
    }


    PCS_power_self = get_cur_power();;
    PCS_power_all = PCS_power_self + get_total_pcs_val();;
    ems_num = get_discover_dev_num();
    DA = dev_get_dev_tag_int(DEV_NO_EMS, DYNAMIC_AUGMENT);
    charge_power = -fabs(dev_get_dev_tag_float(DEV_NO_EMS, CHARGE_MAX_POWER));
    discharge_power = fabs(dev_get_dev_tag_float(DEV_NO_EMS, DISCHARGE_THRES_HOLD));
    */
    static int flag = 0;
    int dis_power_en = 0;

    if(microgrid_data.grid_power > microgrid_ctrl.upper_limit && (int)microgrid_data.pcs_power == 0)
    {
        if(flag != 1)
        {
            xl_antiReflux(0, 0,0, 0, 0, 0, 0, 1);
        }
        flag = 1;
    }
    else if(microgrid_data.grid_power < microgrid_ctrl.lower_limit && (int)microgrid_data.pcs_power == 0)
    {
        if(flag != 2)
        {
            xl_antiReflux(0, 0,0, 0, 0, 0, 0, 1);
        }
        flag = 2;
    }
    cabinet_bms_protect();  // 放电保护
    
    double BMS_power = cabinet_bms_centering();     // 充电回中
         
    if(flag == 1)
    {

        /* 对等设计
        if(ems_num > 1)
        {
            grid_input = (PCS_power_all * k_val - PCS_power_self)/ ems_num * (1 - k_val)  + (grid - microgrid_ctrl.upper_limit) / ems_num + grid / ems_num;
        }
        else 
        {
            grid_input = grid;
            ems_num = 1;
        }
        */

        if(microgrid_data.grid_power >= microgrid_ctrl.upper_limit)
        {
            UD_log_sprintf(micro_log, "\n增容上限保护");
            PCS_power = xl_antiReflux(
            microgrid_data.grid_power, 
            microgrid_ctrl.upper_limit + microgrid_ctrl.DemandDiff, 
            1, 
            microgrid_ctrl.dischargeMaxPower/*系统最大放电功率*/, 
            0, 
            microgrid_data.pcs_power, 
            microgrid_ctrl.upper_limit, 
            0);

            microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
            UD_log_sprintf(micro_log, "\n需量算法期望功率 %lf", microgrid_ctrl.pcs_exp_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 需量算法期望功率 %lf", microgrid_ctrl.pcs_exp_power);

            traverse_cab_dev_func(cabinet_pcs_exp_power_set);   // 先分发期望功率 随后处理实际下发功率
            traverse_cab_dev_func_arg( DCE_discharge_mppt_exp_power, &PCS_power); //
            dis_power_en = 0;
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_DYNAMIC_CAP_STATE, NULL, "动态增容放电逻辑");
        }
        else {
            dis_power_en = 1;
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_DYNAMIC_CAP_STATE, NULL, "动态增容静置逻辑");
        }
        

    }
    else if(flag == 2)
    {   
        if(time_charge_en && BMS_power < 0)  // 时间满足则充电 且 需要充电
        {
            double _limit = 0;
            double _limit_diff = 0;

            // write_self_pcs_status(0);
            /*

            ems_num = get_discover_dev_num();
            plan_power = ;
            cur_power = get_cur_power();
            write_self_pcs_val_and_k3(cur_power, g_usercfg_variant.K3);

            P2 = cur_power + get_total_pcs_val();
            P3 = P1 + P2;
            dev_set_dev_tag_float(DEV_NO_EMS, GRID_ACT_POWER, P1);
            dev_set_dev_tag_float(DEV_NO_EMS, LOAD_ACT_POWER, P3);
            ems_syslog(LOG_NOTICE, "P1=%f, P2= %f, P3=%f  ems_num = %d", P1, P2, P3, ems_num);

            if (ems_num < 1)
            {
                ems_syslog(LOG_ERR, "发现的柜子数量不正确，柜子数量:%d", ems_num);
                continue;
            }
            
            if(g_usercfg_variant.K3 == 0)
                k_val = 0;
            else
            {
                float ex_total_pcs = 0;
                int ex_total_k3 = 0;
                get_extern_agv_pcs_val(&ex_total_pcs, &ex_total_k3);

                k_val = (double)g_usercfg_variant.K3 / (ex_total_k3 + g_usercfg_variant.K3);
            }
            */
            // grid + (PCS_tmp * val->k - result) / 5 * (1 - val->k);
            // dev_get_dev_tag_float(DEV_NO_GRID_MT, METER_POWER) + (P2 * k_val - cur_power) / 5 * (1 - k_val)
        
            /* 特别说明！需量保护部分 不会控制PCS无功，若有对PCS无功的同步调控操作 本段代码需调整*/
            if(microgrid_ctrl.EnProtectTransf == 1) // 变压器需量
            {

                float k1 = g_usercfg_variant.K1;
                UD_log_sprintf(micro_log, "\n使能变压器保护");

                k1 = k1 / 100;
                if(k1 < 0 || k1 > 1)
                {
                    ems_syslog(LOG_ERR, "function: ems_stratagy_period_ctrl : 输入参数非常规g_usercfg_variant.K1 = %d!", g_usercfg_variant.K1);
                }
                else 
                {
                    _limit =  microgrid_ctrl.Pmlmax * ((double)microgrid_ctrl.K1 / 100.0);
                    // grid = dev_get_dev_tag_float(DEV_NO_GRID_MT, APPARENT_POWER);
                    // if(ems_num > 1)
                    // {
                    //     grid_input = (P2 * k_val - PCS_P_var)/ ems_num * (1 - k_val)  + (grid - (double)g_usercfg_variant.Pmlmax * k1) / ems_num + grid / ems_num;
                    //     // grid_input = (grid + (grid + ((double)g_usercfg_variant.Pmlmax / ems_num - (double)g_usercfg_variant.Pmlmax * k1 / ems_num) + (grid - (double)g_usercfg_variant.Pmlmax * k1)) * k_val + (P2  * k_val - PCS_P_var))/ ems_num * (1 - k_val);
                    // }
                    // else {
                    //     grid_input = grid;
                    //     ems_num = 1;
                    // }
                    _limit = _limit > microgrid_ctrl.lower_limit ? microgrid_ctrl.lower_limit : _limit;
                    _limit_diff =_limit;
                    _limit = _limit_diff + microgrid_ctrl.PmlmaxDiff;

                    cur_power_HV = xl_antiReflux(microgrid_data.grid_appower, 
                    _limit, 
                    1, 
                    0, 
                    microgrid_ctrl.chargeMaxPower, 
                    microgrid_data.pcs_power, 
                    _limit_diff, 
                    0);

                    UD_log_sprintf(micro_log, "\n期望上限 %lf", cur_power_HV);
                    
                }
                
                // double temp = fabs(cur_power * cur_power) - fabs(PCS_S_var * PCS_S_var);
                // cur_power_HV = -fabs(sqrt(temp < 0 ? 0 : temp));
                // 注释代码为后续加入无功计算视在功率
            }
            {
                
                if(microgrid_ctrl.EnProtectTransf == 2)
                {
                    UD_log_sprintf(micro_log, "\n使能需量保护");

                    _limit_diff = microgrid_ctrl.lower_limit;
                    _limit = _limit_diff + microgrid_ctrl.DemandDiff;

                    double tmp_limit = microgrid_ctrl.MaxDemand - microgrid_ctrl.PmlmaxDiff;

                    _limit = microgrid_ctrl.MaxDemand > _limit ? _limit : microgrid_ctrl.MaxDemand;
                    _limit_diff = _limit_diff < tmp_limit ? tmp_limit : _limit_diff;
                    UD_log_sprintf(micro_log, "\n _limit = ", _limit);
                    UD_log_sprintf(micro_log, "\n _limit_diff = ", _limit_diff);

                }
                else 
                {
                    _limit_diff = microgrid_ctrl.lower_limit;
                    _limit = _limit_diff + microgrid_ctrl.DemandDiff;
                }
                /*
                double max_demand = dev_get_dev_tag_int(DEV_NO_EMS, MAX_DEMAND);    // 门限
                grid = dev_get_dev_tag_float(DEV_NO_GRID_MT, METER_POWER); // 使用有功功率
                max_demand = (double)g_usercfg_variant.Pmlmax  < max_demand ? g_usercfg_variant.Pmlmax : max_demand;
                
                double max_demand_limit = dev_get_dev_tag_int(DEV_NO_EMS, DEMAND_MARGIN);
                max_demand_limit = max_demand - (max_demand_limit > 0 ? max_demand_limit : 0);
                max_demand_limit = max_demand_limit > 0 ? max_demand_limit : 0;

                if(ems_num > 1)
                {
                    grid_input = (P2 * k_val - PCS_P_var)/ ems_num * (1 - k_val)  + (grid - max_demand_limit) / ems_num + grid / ems_num;
                }
                else 
                {
                    grid_input = grid;
                    ems_num = 1;
                }
                */

                double cur_power_HV_tmp = 0;

                cur_power_HV_tmp = demand_antiReflux(
                    microgrid_data.grid_power, 
                    _limit,
                    1, 
                    0/*系统最大放电功率*/, 
                    microgrid_ctrl.chargeMaxPower, 
                    microgrid_data.pcs_power, 
                    _limit_diff,
                    0);
                if(g_usercfg_variant.EnProtectTransf == 1)
                {
                    cur_power_HV = cur_power_HV_tmp < cur_power_HV ? cur_power_HV : cur_power_HV_tmp;
                }
                else {
                    cur_power_HV = cur_power_HV_tmp;
                }
                UD_log_sprintf(micro_log, "\n cur_power_HV = %lf", cur_power_HV);

            }
            
            if (microgrid_ctrl.EnProtectTrasLV == 1)
            {
                float k4 = g_usercfg_variant.K4;
                k4 = k4 / 100;
                if(k4 < 0 || k4 > 1)
                {
                    ems_syslog(LOG_ERR, "function: ems_stratagy_period_ctrl : 输入参数非常规g_usercfg_variant.K1 = %d!", g_usercfg_variant.K1);
                }
                else 
                {
                    /*
                    grid = dev_get_dev_tag_float(DEV_NO_GRID_MT, APPARENT_POWER);
                    if(ems_num > 1)
                    {
                        grid_input = (P2 * k_val - PCS_P_var)/ ems_num * (1 - k_val)  + (grid - (double)g_usercfg_variant.PLVmlmax * k4) / ems_num + grid / ems_num;
                    }
                    else {
                        grid_input = grid;
                        ems_num = 1;
                    }
                    */
                    
                    _limit_diff = microgrid_ctrl.PLVmlmax * k4;
                    _limit = _limit_diff + microgrid_ctrl.PmlmaxDiff;
                    cur_power_LV = xl_LV_antiReflux(microgrid_data.grid_lv_appower, 
                    _limit, 
                    1, 
                    0, 
                    microgrid_ctrl.dischargeMaxPower, 
                    microgrid_data.pcs_power,
                    _limit_diff, 
                    0);
                }


            }
            if(g_usercfg_variant.EnProtectTransf)
            {
                if(g_usercfg_variant.EnProtectTrasLV)
                {
                    if(cur_power_LV < cur_power_HV)
                    {
                        PCS_power = cur_power_HV;
                    }
                    else {
                        PCS_power = cur_power_LV;
                    }
                }
                else {
                    PCS_power = cur_power_HV;
                }
                
            }
            else {
                PCS_power = cur_power_HV;
                if(g_usercfg_variant.EnProtectTrasLV)
                    PCS_power = cur_power_LV;
            }
            
            microgrid_ctrl.pcs_exp_power = PCS_power;
            UD_log_sprintf(micro_log, "\n 总期望PCS功率 %lf", microgrid_ctrl.pcs_exp_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 总期望PCS功率 %lf", microgrid_ctrl.pcs_exp_power);

            traverse_cab_dev_func(cabinet_pcs_exp_power_set);   // 分发各个柜子最大期望充电功率
            PCS_power = 0;
            traverse_cab_dev_func_arg( DCE_charge_pcs_mppt_exp_power, &PCS_power); //
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_DYNAMIC_CAP_STATE, NULL, "动态增容充电逻辑");
        }
        else {
            dis_power_en = 2;
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_DYNAMIC_CAP_STATE, NULL, "动态增容静置逻辑");
        }
    }

    if(dis_power_en) 
    {
        if(microgrid_ctrl.EnTraceLoad)
        {
            UD_log_sprintf(micro_log, "\n<负荷跟踪模式>\n");
            double grid = dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power;
            if(microgrid_ctrl.en_anti_reflux)
            {
                grid -= microgrid_ctrl.anti_reflux;
                UD_log_sprintf(micro_log, "\n<使能防逆流 附带防逆流余量保护>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "动态增容:使能负荷跟踪与防逆流");

            }
            else 
            {
                UD_log_sprintf(micro_log, "\n<未使能防逆流 算法误差将可能在负载处于极低功率下导致些许逆流>\n");
                BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "动态增容:使能负荷跟踪");
            }
            PCS_power = antiReflux(
                grid - (grid + microgrid_data.pcs_power) * microgrid_ctrl.TraceLoad , 
                1,  
                1,
                microgrid_ctrl.dischargeMaxPower, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, "\n<负荷跟踪算法期望功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 负荷跟踪算法期望功率: %lf", PCS_power);

        }
        else if(microgrid_ctrl.en_anti_reflux)
        {
            

            PCS_power = antiReflux(
                dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.act_power, 
                microgrid_ctrl.anti_reflux,  
                1, 
                microgrid_ctrl.dischargeMaxPower, 
                0, 
                microgrid_data.pcs_power, 
                0);
            UD_log_sprintf(micro_log, " \n<使能防逆流,算法推导PCS期望功率:%lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 使能防逆流,算法推导PCS期望功率:%lf", PCS_power);
        }
        else
        {
            PCS_power = microgrid_ctrl.dischargeMaxPower;  // plan约束                
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_TRACELOAD, NULL, "动态增容:未使能负荷跟踪 将按照策略:%f 下发", PCS_power);
            BUSINESS_LOG(BLOG_NOTICE, ALG_ID_ANTIREFLUX, NULL, "动态增容:未使能防逆流 将按照策略:%f 下发", PCS_power);
            UD_log_sprintf(micro_log, "\n<未使能防逆流 将按照系统最大放电功率: %lf>\n", PCS_power);
            BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 未使能防逆流 将按照系统最大放电功率: %lf", PCS_power);

        }
        microgrid_ctrl.pcs_exp_power = PCS_power;
        traverse_cab_dev_func(cabinet_pcs_exp_power_set);   // 先分发期望功率 随后处理实际下发功率
        PCS_power = 0;
        traverse_cab_dev_func_arg( DCE_stewing_mppt_exp_power, &PCS_power); //
    }

    microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
    PCS_set_power(PCS_power, 0);    // 功率下发
    MPPT_set_power(MPPT_power, 0);  // 功率下发
    
    return 0;
}

/**
 * @description: 直流模式
 * @return {*}
 */
static int Grid_connected_mode()
{
    UD_log_sprintf(micro_log, "\n<策略：[%d]   %d:计划功率 %d:动态增容 %d:自发自用 %d:光储备电>\n", microgrid_ctrl.choose_func, STRATAGY_TYPE_PERIOD_CTRL, STRATAGY_TYPE_DEMAND_FIXED, STRATAGY_TYPE_PV_STORAGE, STRATAGY_TYPE_STANDBY);
    BUSINESS_LOG(LOG_NOTICE, DC_ID_0008, NULL, "[直流耦合]: 策略：[%d]   %d:计划功率 %d:动态增容 %d:自发自用 %d:光储备电", microgrid_ctrl.choose_func, STRATAGY_TYPE_PERIOD_CTRL, STRATAGY_TYPE_DEMAND_FIXED, STRATAGY_TYPE_PV_STORAGE, STRATAGY_TYPE_STANDBY);
    switch(microgrid_ctrl.choose_func) // 业务逻辑选择
    {
        case STRATAGY_TYPE_PERIOD_CTRL/*削峰填谷模式*/:
            peakLoadShifting();

        break;
        case STRATAGY_TYPE_DEMAND_FIXED/*动态增容*/:
            Dynamic_capacity_expansion();
        return 0;
        break;
        case STRATAGY_TYPE_PV_STORAGE/*光伏消纳*/:
            PhotovoltaicAbsorption();
        break;
        case STRATAGY_TYPE_STANDBY/*光储备电*/:
            Emergency_backup_power();
        return 0;
    
        default:
        break;
    }
    return 0;

}



RELEVANCE_STATE init_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    /**///ems_syslog(LOG_ERR,"init_init");  // TODO 进异常
    sleep(5);   // 等待三秒获取数据
    Relevant_data_refresh();
    // 如果没能使能光伏 尝试将光伏关掉 没关掉也没事 也许就没光伏这设备 
    if(1 == microgrid_cfg.en_photovoltaic && 1 == mppt_stop())
    {
        ems_syslog(LOG_ERR,"Err: MPPT power does not write 0!!!!");  // TODO 进异常
    }

    return state;
}

RELEVANCE_STATE init_handover_detect(RELEVANCE_STATE state)
{
    
    Relevant_data_refresh();        // 刷新数据源
    RELEVANCE_STATE state_set = resolve_state();

    /*TODO: 增加DIDO校验 DIDO优先级更高*/
   
    return state_set;
}

int init_behaviour_func(RELEVANCE_STATE state_self)
{
    sleep(1);
    return 0;
}




/**
 * @description: 进入待机模式:
                必然动作:PCS关机、MPPT停止
                
 * @param {RELEVANCE_STATE} last_state
 * @param {RELEVANCE_STATE} state
 * @return {*}
 */
RELEVANCE_STATE await_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
        /**///ems_syslog(LOG_ERR,"await_init");  // TODO 进异常

    /*MPPT写0功率*/
    int ret = 0;

    if(microgrid_cfg.en_photovoltaic && mppt_stop())
    {   // TODO: 修改光伏功率下发接口
        ems_syslog(LOG_ERR,"Err: MPPT power does not write 0!!!!");  // TODO 进异常

    }
    ret |= set_pcs_onoff(0);

    if(ret)
    {

        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;
    }
    /* PCS 关机 */

    return state;
}

RELEVANCE_STATE await_handover_detect(RELEVANCE_STATE state)
{
    Relevant_data_refresh();        // 刷新数据源
    
    RELEVANCE_STATE state_set = resolve_state();
    struct _dido_t *dido = &dev_info_all.dido.dido_param[0];
    if((microgrid_cfg.en_sts == 0 && dido->info.dido_data.conn_sign == 0) || (microgrid_cfg.en_sts && microgrid_data.grid_statu == 0))    // 离网状态的待机 尝试启动柴发
    {
        if(microgrid_cfg.en_diesel_generator)
        {
            set_dg_statu(1, 0);
        }
        
    }



    if(microgrid_data.SOC_average >= microgrid_ctrl.SOC_max_netdead) // 充满电了先关光伏
    {
        mppt_stop();
    }

    /*否则等SOC充满切回离网  条件判定基于上一状态是否为离网状态 否则其他状态嵌入本状态将导致需要充满电才能切出 */
    if((state_set == STATE_OFF_GRID || state_set == STATE_AWAIT) && microgrid_data.SOC_average < microgrid_ctrl.SOC_max_netdead && state_machine_Micgp.last_state == STATE_OFF_GRID)
    {
        
        state_set = state;
    }

    if(state_set == state && ((microgrid_cfg.en_sts == 0 && dido->info.dido_data.conn_sign == 1) || (microgrid_cfg.en_sts && microgrid_data.grid_statu == 1)))    // 并网待机模式保持 icb 闭合
    {
        dido_set_icb(1, 0);
    }

    
    pcs_stop();
    set_pcs_onoff(0);

    return state_set;
}

/*待机策略中 若长期处于待机状态 可支持使用光伏对BMS充电*/
int await_behaviour_func(RELEVANCE_STATE state_self)
{
    if(Relevant_data_refresh())
    {
        return 0;
    }

    double BMS_power = cabinet_bms_centering();
    double MPPT_power = 0 - BMS_power;

    MPPT_power = microgrid_ctrl.mppt_exp_power < 0 ? 0 : microgrid_ctrl.mppt_exp_power;
    if(microgrid_cfg.en_photovoltaic)
    {
        traverse_cab_dev_func(cabinet_mppt_exp_power_set);
        MPPT_set_power(MPPT_power, 0);
    }

    return 0;
}



RELEVANCE_STATE connect_grid_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    /**///ems_syslog(LOG_ERR,"connect_grid_init");  // TODO 进异常
    int ret = 0;
    if(0 == microgrid_cfg.en_sts && STATE_AWAIT == last_state)   // 如果上一状态是待机状态 PCS就视为关机状态 
    {
        /* PCS 并网 */
        if(pcs_check_connect(1))    // 校验并离网状态
        {
            ret |= set_pcs_onoff(0);
            ret |= set_pcs_connect(1);
        }
    }
     /* PCS 开机 */
    ret |= set_pcs_onoff(1);

    if(ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return  STATE_ABNORMAL;
    }

    return STATE_CONNECT_GRID;

}

RELEVANCE_STATE connect_grid_handover_detect(RELEVANCE_STATE state)
{

    Relevant_data_refresh();
    RELEVANCE_STATE state_set = resolve_state();

    int ret = 0;
    if(microgrid_cfg.en_diesel_generator && get_dg_statu())
    {
        set_dg_statu(0, 0);    // 柴发关掉
    }

    dido_set_icb(1, 0);

    if(0 == microgrid_cfg.en_sts && pcs_check_connect(1))    // 校验并离网状态
    {
        mppt_stop();            // 先停光伏 将PCS切并网再loop
        ret |= set_all_pcs_onoff_tag_pcs_auto(0);
        ret |= set_pcs_connect(1);
    }
     /* PCS 开机 */
    ret |= set_all_pcs_onoff_tag_pcs_auto(1);

    if (ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;
    }
    
    return state_set;
}


int connect_grid_behaviour_func(RELEVANCE_STATE state_self)
{

    /**///ems_syslog(LOG_ERR,"connect_grid_behaviour_func");  // TODO 进异常

    if(Relevant_data_refresh())
    {
        return 0;
    }

    if (dev_info_all.meter_grid.meter_grid_param[0].info.meter_grid_data.on_line){
        Grid_connected_mode();
    }
    else{ // 关口表离线
        pcs_stop();
        mppt_stop();
        UD_log_sprintf(micro_log, " \n错误，关口表离线!!!\n");
    }
   
    return 0;
}


RELEVANCE_STATE off_grid_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    int ret = 0;
    Relevant_data_refresh();
    if(1 != microgrid_cfg.en_sts)
    {
        set_pcs_onoff(0);
        ret |= set_pcs_connect(0);
    }
    ret |= set_pcs_onoff(1);

    if(ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;
    }
  
    return state;

}

RELEVANCE_STATE off_handover_detect(RELEVANCE_STATE state)
{
    int ret = 0;
    Relevant_data_refresh();
    RELEVANCE_STATE state_set = resolve_state();
    
    if(microgrid_data.SOC_average <= microgrid_ctrl.SOC_min_netdead) // SOC低阈值 切待机模式
    {
        mppt_stop();        
        return STATE_AWAIT; // 直接切入待机
    }

    if(microgrid_cfg.en_diesel_generator)
    {
        if(microgrid_ctrl.dg_boot_soc > microgrid_data.SOC_average)
        {
            set_dg_statu(1, 0);
        }
        else 
        {
            if(get_dg_statu())
                set_dg_statu(0, 0);
        }
    }

    dido_set_icb(0, 0);     // 内置使能检查

    if(0 == microgrid_cfg.en_sts)
    {
        if(pcs_check_connect(0))
        {
            ret |= set_pcs_onoff(0);
            ret |= set_pcs_connect(0);
        }
    }

    ret |= set_pcs_onoff(1);

    if(ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;  // 进异常
    }

    return state_set;
}


int off_grid_behaviour_func(RELEVANCE_STATE state_self)
{
    /**///ems_syslog(LOG_ERR,"off_grid_behaviour_func");  // TODO 进异常
    off_grid_mode();

    return 0;
}

RELEVANCE_STATE dg_mode_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    if(1 != microgrid_cfg.en_diesel_generator)  // 柴发使能开关校验
    {
        return STATE_INIT;
    }
   
    int ret = 0;
    mppt_stop();            // 先停光伏
    if(microgrid_cfg.en_sts)
    {
        
    }
    else 
    {
        if(microgrid_cfg.en_photovoltaic)   // 具备光伏条件下，储能采取光伏充电 避开市电
        {
            ret |= set_pcs_onoff(0);
            
        }
        else
        {   if(pcs_check_connect(1))        //并离网切换
            {
                ret |= set_pcs_onoff(0);
                ret |= set_pcs_connect(1);
            }
            ret |= set_pcs_onoff(1);
        }
        
    
    }

    if(microgrid_cfg.en_icb)        // 断路器合闸
    {
        ret |= dido_set_icb(1, 1);
    }

    if(ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;  // 开关机操作不了 去异常处理
    }

    return state;

}

RELEVANCE_STATE dg_mode_handover_detect(RELEVANCE_STATE state)
{
    Relevant_data_refresh();
    int ret = 0;

    enum _STATE_MICROGRID state_set = resolve_state();
    dido_set_icb(1, 0);
    set_dg_statu(1, 0);
    
    if(microgrid_ctrl.DG_cap_pro)   // 使能容量保护 将采用柴发充电 且优先光伏
    {
        if(0 == microgrid_cfg.en_sts && pcs_check_connect(1))    // 校验并离网状态
        {
            
            ret |= set_pcs_onoff(0);
            ret |= set_pcs_connect(1);
        }
        /* PCS 开机 */
        ret |= set_pcs_onoff(1);

    }
    else 
    {
        ret |= set_pcs_onoff(0);
    }

    if(ret)
    {
        ems_syslog(LOG_ERR, "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        BUSINESS_LOG(LOG_NOTICE, DC_ID_0003, "PCS_log", "操作接口无效, 抛出异常，重启恢复解除| state: %d", state_machine_Micgp.major_state);
        return STATE_ABNORMAL;
    }

    return state_set;
}

int dg_mode_behaviour_func(RELEVANCE_STATE state_self)
{
    Relevant_data_refresh();

    double BMS_power = 0,PCS_power = 0,MPPT_power = 0;
    BMS_power = cabinet_bms_centering();        // 回调会设置 cab->bms_exp_power 
    if(microgrid_ctrl.DG_cap_pro)   // 使能容量保护 将采用柴发充电 且优先光伏
    {
        if(BMS_power < 0)
        {
            double _Pmlmax = microgrid_ctrl.dg_rated_power;
            PCS_power = xl_antiReflux(  // 变压器保护，在保证不超变压器容量的前提下，尽可能靠近充电功率上限
                microgrid_data.dg_repower, 
                _Pmlmax,
                1, 
                0/* fabs(microgrid_ctrl.discharge_max_set)*/, 
                microgrid_ctrl.chargeMaxPower,
                microgrid_data.pcs_power, 
                _Pmlmax - microgrid_ctrl.DgDiff,
                0);
            traverse_cab_dev_func_arg(set_pcs_ctrl_chargepower, &PCS_power);

        }
        else { 
            PCS_power = 0;
        }

        microgrid_ctrl.pcs_exp_power = PCS_power;   // 刷新期望功率
        traverse_cab_dev_func(cabinet_pcs_exp_power_set);   // 先分发期望功率 随后处理实际下发功率
        MPPT_power = 0;
        traverse_cab_dev_func_arg(peakLoadShifting_pcs_mppt_exp_power, &MPPT_power);
    }
    else
    {
        if(microgrid_cfg.en_photovoltaic)
        {
            PCS_power = 0;
            microgrid_ctrl.pcs_exp_power = 0;
            traverse_cab_dev_func_arg(set_pcs_ctrl_chargepower, &PCS_power);

            traverse_cab_dev_func_arg(mppt_exp_power_set, &MPPT_power);  // 处理单柜期望功率
        }
    }

    PCS_set_power(PCS_power, 0);
    MPPT_set_power(MPPT_power, 0);

    return 0;
}

/**
 * @description: 异常处理
 * @param {RELEVANCE_STATE} last_state
 * @param {RELEVANCE_STATE} state
 * @return {*}
 */
RELEVANCE_STATE ABNORMAL_init(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    
    set_pcs_onoff(0);
    mppt_stop();

    return state;
}

RELEVANCE_STATE ABNORMAL_handover_detect(RELEVANCE_STATE state)
{
    static int en = 0;
    static struct lnxall_buff buff;
    buff.bufptr = "";

    if(0 == en)
    {
        lbuff_init(&buff, 10);
        lbuff_sprintf(&buff, "%s", micro_log->prt_buf.bufptr);
        en = 1;
    }
    else
    {
        UD_log_sprintf(micro_log, " \n%s\n", buff.bufptr);
    }
    UD_log_sprintf(micro_log, " \n<ERROR 微网业务异常 请排查 本状态不会退出, 需退出请重启EMS进程>\n");
    set_pcs_onoff(0);
    mppt_stop();

    return state;
}


int ABNORMAL_behaviour_func(RELEVANCE_STATE state_self)
{
  
    return 0;
}


static RELEVANCE_STATE states_exit(RELEVANCE_STATE last_state, RELEVANCE_STATE state)
{
    PCS_set_power(0, 1);
    MPPT_set_power(0,1);
    mppt_stop();
    microgrid_ctrl.pcs_auto_statu = 0;
    return state;
}



/**
 * @description: 微网并离网状态机初始化
 * @return {*} -1 指针悬空状态机初始化失败  0 空
 */
int state_machine_Init()
{
    /*待开发完善*/
    state_machine_Micgp.state[STATE_INIT].handover_detect = init_handover_detect;
    state_machine_Micgp.state[STATE_INIT].behaviour_func = init_behaviour_func;
    state_machine_Micgp.state[STATE_INIT].init = init_init;
    state_machine_Micgp.state[STATE_INIT].state_self = STATE_INIT;

    state_machine_Micgp.state[STATE_AWAIT].handover_detect = await_handover_detect;
    state_machine_Micgp.state[STATE_AWAIT].behaviour_func = await_behaviour_func;
    state_machine_Micgp.state[STATE_AWAIT].init = await_init;
    state_machine_Micgp.state[STATE_AWAIT].state_self = STATE_AWAIT;

    state_machine_Micgp.state[STATE_CONNECT_GRID].handover_detect = connect_grid_handover_detect;
    state_machine_Micgp.state[STATE_CONNECT_GRID].behaviour_func = connect_grid_behaviour_func;
    state_machine_Micgp.state[STATE_CONNECT_GRID].init = connect_grid_init;
    state_machine_Micgp.state[STATE_CONNECT_GRID].state_self = STATE_CONNECT_GRID;

    state_machine_Micgp.state[STATE_OFF_GRID].handover_detect = off_handover_detect;
    state_machine_Micgp.state[STATE_OFF_GRID].behaviour_func = off_grid_behaviour_func;
    state_machine_Micgp.state[STATE_OFF_GRID].init = off_grid_init;
    state_machine_Micgp.state[STATE_OFF_GRID].state_self = STATE_OFF_GRID;

    /*柴发并网暂时不参与*/
    state_machine_Micgp.state[STATE_CF_CONNECT_GRID].handover_detect = dg_mode_handover_detect;
    state_machine_Micgp.state[STATE_CF_CONNECT_GRID].behaviour_func = dg_mode_behaviour_func;
    state_machine_Micgp.state[STATE_CF_CONNECT_GRID].init = dg_mode_init;
    state_machine_Micgp.state[STATE_CF_CONNECT_GRID].state_self = STATE_CF_CONNECT_GRID;

    /*未定义状态无法确定逻辑*/
    state_machine_Micgp.state[STATE_ABNORMAL].handover_detect = ABNORMAL_handover_detect;
    state_machine_Micgp.state[STATE_ABNORMAL].behaviour_func = ABNORMAL_behaviour_func;
    state_machine_Micgp.state[STATE_ABNORMAL].init = ABNORMAL_init;
    state_machine_Micgp.state[STATE_ABNORMAL].state_self = STATE_ABNORMAL;

    state_machine_Micgp.states_exit = states_exit;
 
    Relevant_data_refresh();        // 刷新数据源


    state_switch(&state_machine_Micgp, STATE_INIT);      // 初始状态 
   

    pthread_t pid;// 微网状态机线程
    pthread_create(&pid, NULL, state_machine_pthread, &state_machine_Micgp);
    if (pthread_setname_np(pid, "Microgrid")) 
    { 
        ems_syslog(LOG_ERR,"Error setting thread name\n"); 
        return 1; 
    }
    return 0;

}
