#ifndef MICRO_DC_GRID__
#define MICRO_DC_GRID__

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <math.h>   
#include "../cc_lc_com/define.h"
#include "../cc_lc_com/collector-api.h"
#include "../common.h"
#include "./discover.h"
#include "./jsonct.h"
#include "lc.h"
#include "pub_fun.h"
#include "log_upper_data.h"
#include "utils.h"
#include "../business_log/business_log.h"

#define PV_POWER_THRESHOLD 1     // 1KW

typedef struct 
{
    int code;
    char *msg;
} micro_error_code_msg_t;

typedef enum
{
    _SUCCESS = 0,
    BMS_ERR = 1,
    PCS_ERR,     
    MPPT_ERR, 
    METER_PCS_ERR,  
    METER_MPPT_ERR,
    PV_ERR, 
    METER_PV_ERR, 
    METER_GRID_ERR,
    METER_LOAD_ERR,
    METER_DG_ERR,
    _MAX
} dev_serial_t;

#define LIMIT_RANGE(_data, _min, _max) \
    do                                 \
    {                                  \
        if (_data < _min)              \
        {                              \
            _data = _min;              \
        }                              \
        else if (_data > _max)         \
        {                              \
            _data = _max;              \
        }                              \
    } while (0);
/**
 * @description: 针对功能下发并校验的接口 其结构固定 
                便可封装于此 使用宏而非函数是为了简略回调函数的入参 可便于回调入参与宏上下文
                且结构化的代码并不会增加复杂度
 * @param {int (*func)(...)} _func_1: 执行某一函数功能          0:成功 1:失败
 * @param {int (*func)(...)} _func_2: 检查该功能执行成功与否    0:成功 1:失败
 * @param {int} __sleep_time: _func_1 的执行间隔
 * @param {int} __overtime: 本次校验超时时间
 * @param {int} result: 返回值
 * @return {*}
 */
#define release_confirmation(_func_1, _func_2, __sleep_time, __overtime, result)\
        do {\
            result = 1;\
            if(0 == _func_2)\
            {\
                result = 0;\
                break;\
            }\
            time_t __now = time(NULL);\
            time_t __now_tmp = __now;\
            do\
            {\
                if(0 == (__now_tmp - __now) % __sleep_time)\
                {if(1 == _func_1){result = 1; break;};}\
                sleep(1);\
                __now_tmp = time(NULL);\
                result = _func_2;\
            }while (result && (__now_tmp - __now < __overtime));\
        }while (0)\

/*并网离网门限判断*/
#define GRID_V_MIN  20   // 电网低电压门限
#define GRID_V_MAX  200  // 电网高电压门限



#define INDEX_METER_GRID    0       // 设备数组索引
#define INDEX_METER_LV      1       // 设备数组索引

// 微网拓扑模式    0:禁用微网    1:微网直流并离网模式    2:微网交流并离网模式


/**
 * @description: 充放电状态
 */
enum ENERGY_DIRECTION
{
    ENERGY_DEFAULT = 0,
    DISCHARGE_DIRECTION,
    CHARGE_DIRECTION,
};
#define MICR_ACTION_TYPE_INIT -1
#define CONDITION_NUM_MAX  10

typedef enum {
    LOGIC_AND,
    LOGIC_OR
} LogicRelation;

#define CHECK_CONDITIONS(check, logic, pos) \
    do { \
        bool result = (logic == LOGIC_AND); \
        for (int i = 0; i < CONDITION_NUM_MAX; i++) { \
            if (check->conditions[i].func != NULL) { \
                if (logic == LOGIC_AND) { \
                    result &= check->conditions[i].func(var, check->conditions[i].param, pos); \
                } else if (logic == LOGIC_OR) { \
                    result |= check->conditions[i].func(var, check->conditions[i].param, pos); \
                } \
            } \
            else \
                break; \
        } \
        return result; \
    } while (0)\

#define IS_KEY 1
#define NOT_KEY 0

extern struct UD_log *ac_micro_log;

#define micro_ac_log(level, mainid, obj_id, key, fmt, ...)               \
    do                                                                   \
    {                                                                    \
        char __buf[4096] = {0};                                          \
        snprintf(__buf, sizeof(__buf), fmt, ##__VA_ARGS__);              \
        ems_syslog(level, "[micro_ac] %s", __buf);                       \
        if (key){                                                        \
            UD_log_sprintf(ac_micro_log, "%s \n", __buf);                \
            BUSINESS_LOG(level, mainid, obj_id, "[交流耦合]: %s", __buf); \
        }                                                                \
    } while (0)

enum ALG_ID_LIST
{
    ALG_ID_INI = 5000,
    ALG_ID_ANTIREFLUX,
    ALG_ID_XL_ANTIREFLUX_TRAN,
    ALG_ID_XL_ANTIREFLUX_DEMAND,
    ALG_ID_XL_ANTIREFLUX_LV_TRAN,
    ALG_ID_DYNAMIC_CAP_STATE,
    ALG_ID_TRACELOAD,
    ALG_ID_SWD2C,
    ALG_ID_SWC2D,
    ALG_ID_RC,
    ALG_ID_EMS_NUM,
    ALG_ID_MAX = 5200,
};

/*电池状态*/
typedef enum
{
    STATE_UK = -1,            // 未知
    STATE_EMPTY = 0,          // 放空
    STATE_FULL,               // 满充
    STATE_OR,                 // 可充可放
}_STATE_BATTERY;

typedef struct
{
    int chargefull;
    int dischargefull;
}battery_flag_t;

typedef enum 
{
    MICR_CONDITION_OK,
    MICR_CONDITION_SKIP,
    MICR_CONDITION_NO_MATCH,
} MICR_CONDITION_E;

typedef enum
{
    ERROR_LC = -1,
    LC = 0,
    LC1,     
    LC2, 
    LC3,  
    LC4,
    LC5, 
    LC6, 
    LC7, 
    LC8, 
    LC9, 
    LC10, 
    LC11, 
    LC12, 
    LC13, 
    LC14,
    LC15,
    _MAX_LC
} lc_serial_t;

#define CABINET_NUM_MAX  16 
#define DEV_NUM_MAX  32 

struct pcs_cfg_t
{
    double scale;                               // 装机比例  
};

struct pcs_ctrl_t
{
    time_t last_time;
	double last_set_power;					// 上一次设置功率
	double out_power_set;					// 输入输出功率-设置功率 负充正放
};

struct pcs_data_t
{
	int on_line;
	double out_power;					// PCS当前输入输出功率获取
	double out_repower;					// PCS当前输入输出功率获取
	int statu;								// 状态 0:关机	1:开机
	int PF_network; 						// 并离网状态
};

struct _pcs_t    
{    
    struct pcs_info_t
    {
        struct pcs_cfg_t pcs_cfg;
        struct pcs_ctrl_t pcs_ctrl;
		struct pcs_data_t pcs_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_PCS_t      // PCS
{
    struct _pcs_t pcs_param[DEV_NUM_MAX];
    int num;
};

struct bms_cfg_t
{
    double scale;       // 功率系数 参考值:scale = 0.5 --> 50% 的设备系统功率

};

struct bms_ctrl_t
{

};

struct bms_data_t
{
	int on_line;							// 是否在线: 1:在线 0:失联
	double SOC; 							// SOC值
	double Vol; 							// 电压
	double Cur; 							// 电流
	double charging_power_max;				// 最大放电功率
	double discharging_power_max;			// 最大充电功率

    double rackVmax;        // 最高单体电压
    double rackVmin;        // 最低单体电压
};

struct _bms_t    
{    
    struct bms_info_t
    {
        struct bms_cfg_t bms_cfg;
        struct bms_ctrl_t bms_ctrl;
		struct bms_data_t bms_data;
    }info;
	
	double charging_power_max;				// 该BMS组 最大放电功率
	double discharging_power_max;			// 该BMS组 最大充电功率
	
    char *no;
	void *ptr;
};

struct Dev_BMS_t     // BMS
{    
    struct _bms_t bms_param[DEV_NUM_MAX];
    int num;

    double soc_max;
	double soc_min;
};

struct meter_pcs_data_t
{
    int on_line;
    double power;                           // 有功功率
    double AphaseVoltage;                   // A相电压
    double BphaseVoltage;                   // B相电压
    double CphaseVoltage;                   // C相电压
};

struct _meter_pcs_t    
{    
    struct meter_pcs_info_t
    {
		struct meter_pcs_data_t meter_pcs_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_METER_PCS_t        // 储能表
{
    struct _meter_pcs_t meter_pcs_param[DEV_NUM_MAX];
    int num;
};

struct meter_pv_data_t
{
	int on_line;
	double power;					        // 有功功率
	double repower;					        // 有功功率
	double AphaseVoltage;                   // A相电压
    double BphaseVoltage;                   // B相电压
    double CphaseVoltage;                   // C相电压
};

struct _meter_pv_t    
{    
    struct meter_pv_info_t
    {
		struct meter_pv_data_t meter_pv_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_METER_PV_t        // 光伏表
{
    struct _meter_pv_t meter_pv_param[DEV_NUM_MAX];
    int num;
};


struct meter_mppt_data_t
{
	int on_line;
	double power;				  // 输出功率
    double Vol;                   // 输出电压
    double Cur;                   // 输出电流
};

struct _meter_mppt_t    
{    
    struct meter_mppt_info_t
    {
		struct meter_mppt_data_t meter_mppt_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_METER_MPPT_t        // 光伏表
{
    struct _meter_mppt_t meter_mppt_param[DEV_NUM_MAX];
    int num;
};

struct pv_cfg_t
{
    double scale;                           // 装机比例   scale =  50 ----> 50%总功率
};

struct pv_ctrl_t
{
	double power_set;					    // 设置 功率/百分比
};

struct pv_data_t
{
	int on_line;
	double power;						    // pv当前输出有功功率
    double repower;
	int statu;							    // 开关机
	int mode;							    // 工作模式 
	double AphaseVoltage;                   // A相电压
    double BphaseVoltage;                   // B相电压
    double CphaseVoltage;                   // C相电压
};

struct _pv_t    
{    
    struct pv_info_t
    {
        struct pv_cfg_t pv_cfg;
        struct pv_ctrl_t pv_ctrl;
		struct pv_data_t pv_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_PV_t        // 光伏pv
{
    struct _pv_t pv_param[DEV_NUM_MAX];
    int num;
};

struct mppt_cfg_t
{
    double scale;                           // 装机比例   scale =  50 ----> 50%总功率
};

struct mppt_ctrl_t
{
	double power_set;					    // 设置功率
    time_t last_time;
    double last_set_power;                  // 上一次设置功率
};

struct mppt_data_t
{
	int on_line;
	double power;						    // 光伏mppt当前输出有功功率
	int statu;							    // 开关机
	int mode;							    // 工作模式 
};

struct _mppt_t    
{    
    struct mppt_info_t
    {
        struct mppt_cfg_t mppt_cfg;
        struct mppt_ctrl_t mppt_ctrl;
		struct mppt_data_t mppt_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_MPPT_t        // 光伏mppt
{
    struct _mppt_t mppt_param[DEV_NUM_MAX];
    int num;
};

struct meter_grid_data_t
{
    int on_line;
    double act_power;                       // 总有功功率
    double rea_power;                       // 总无功功率
    double appr_power;                      // 总视在功率
    double factor;                          // 功率因数
    double AphaseVoltage;                   // A相电压
    double BphaseVoltage;                   // B相电压
    double CphaseVoltage;                   // C相电压
};

struct _meter_grid_t    
{    
    struct meter_grid_info_t
    {
		struct meter_grid_data_t meter_grid_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_METER_GRID_t        // 关口表
{
    struct _meter_grid_t meter_grid_param[DEV_NUM_MAX];
    int num;
};

struct pcu_cfg_t
{

};

struct pcu_ctrl_t
{

};

struct pcu_data_t
{

};

struct _pcu_t    
{    
    struct pcu_info_t
    {
        struct pcu_cfg_t pcu_cfg;
        struct pcu_ctrl_t pcu_ctrl;
		struct pcu_data_t pcu_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_PCU_t                   // 充电桩
{
    struct _pcu_t pcu_param[DEV_NUM_MAX];
    int num;
};

struct meter_load_data_t
{
    int on_line;
    double power;                       // 功率
};

struct _meter_load_t    
{    
    struct meter_load_info_t
    {
		struct meter_load_data_t meter_load_data;
    }info;

    char *no;
	void *ptr;
};

struct _meter_dg_t    
{    
    struct meter_dg_info_t
    {
		struct meter_dg_data_t
        {
            int on_line;
            double act_power;                       // 总有功功率
            double rea_power;                       // 总无功功率
            // double appr_power;                      // 总视在功率
            // double factor;                          // 功率因数
            double AphaseVoltage;                   // A相电压
            double BphaseVoltage;                   // B相电压
            double CphaseVoltage;                   // C相电压
        } meter_dg_data;
    }info;

    char *no;
	void *ptr;
};

struct Dev_METER_LOAD_t        // 负载表
{
    struct _meter_load_t meter_load_param[DEV_NUM_MAX];
    int num;
};

struct Dev_METER_DG_t        // 负载表
{
    struct _meter_dg_t meter_dg_param[DEV_NUM_MAX];
    int num;
};


struct _dido_t     
{    
    struct dido_t
    {
		struct dido_data_t
        {
            int conn_sign;   // 并离网识别反馈    0:离网 1:并网
            int ats_sign;    // ATS反馈          0:副电源 1:主电源    默认主电源为市电
            int lcb_sign;    // 负载断路器反馈    0: 断开  1:闭合
            int icb_sign;    // 并离网断路器反馈  0: 断开  1:闭合
            int DG_sign;     // 柴发启停反馈      0: 停止  1:启动
        }dido_data;

        struct dido_ctrl_t
        {
            _Atomic int icb_ctrl;    // 并离网断路器控制     0: 断开  1:闭合
            _Atomic int lcb_ctrl;    // 负载断路器控制       0: 断开  1:闭合
            _Atomic int DG_ctrl;     // 柴发控制             0: 停止  1:启动
        }dido_ctrl;
    }info;

    char *no;   // NULL!!!
	void *ptr;  // NULL!!!
};

struct Dev_DIDO_t        // DIDO模块
{
    struct _dido_t dido_param[DEV_NUM_MAX]; //虚拟DIDO控制和刷新只在第一个元素中
    int num;
};

typedef struct
{ 
    struct Dev_PCS_t pcs;                   // 逆变器
    struct Dev_BMS_t bms;                   // 主控
    struct Dev_MPPT_t mppt;                 // 光伏MPPT(直)
    struct Dev_METER_PCS_t meter_pcs;       // 储能表
    struct Dev_METER_MPPT_t meter_mppt;     // 光伏表(直)

    struct _ctrl
    {

        double pcs_discharge_max_actual;        // 该柜PCS最大实际可输出功率 = BMS寄存器最大可充可放 用于功率下发时的门限(实际获取的)
        double pcs_charge_max_actual;           // 该柜PCS最大输出功率(实际获取的)
        double pcs_discharge_max_set;           // 该柜PCS最大输出功率 = cfg_power_max * scale(业务控制) 参数用于业务控制门限来限制最大最小功率分配 业务层功率分配后 再由实际进行规限
        double pcs_charge_max_set;              // 该柜PCS最小输出功率(PCS总和 调度逻辑中可变参数 含义:当前门限)
        _Atomic double pcs_exp_power;           // PCS设置功率设置

        double bms_exp_power;                   // bms期望功率      (负充正放)
        int bms_of_charge;                   // 禁充使能
        int bms_of_discharge;                // 禁放使能
        double mppt_exp_power;                  // 光伏期望功率设置（直流侧）
        _Atomic int onoff;                      // 控制开关机
        _Atomic int connect;                    // 控制并离网

        double discharge_max_cfg;               // 该柜PCS最大输出功率(PCS总和) 静态参数
        double charge_max_cfg;                  // 该柜PCS最大输出功率(PCS总和)
        double scale;                           // 该柜设置功率比
        double mppt_power_max;                  // 光伏额定功率配置
        int RTM_EN;                  // 柜归中标记
    }cab_ctrl;

    struct _data
    {
        double SOC_average;
        double SOC_ceiling;
        double SOC_floor;
        double pcs_output_power;                // PCS实际输出功率
        double pcs_output_repower;              // PCS实际无功输出功率
       
        int on_line;
        int onoff;                              // 开关机 状态 (回读LC)
        int connect;
        double mppt_out_power;                  // mppt实际输出功率

        _STATE_BATTERY battery_sta;             // 柜电池状态
        int en;                                 // 0:Normal;1:Abnormal; 
        int prohibited_char;                    // 禁充保护
        int prohibited_dischar;                 // 禁放保护
        int rackVmax;
        int rackVmin;
        int singleVmaxtime; // 时间戳检查点
        int singleVmintime; // 时间戳检查点
        int single_cell_alarm;

    }cab_data;

    struct _cfg
    {
        
        int capacity;                           // 柜容量
        double scale;                           //  该柜配置功率比

        double mppt_power_max;                  // 光伏期望功率设置（直流侧）

    }cab_cfg;

    char *no;
    char *ptr;
    pthread_t action_thread;
}cabinet_inside_t;

typedef struct    
{    
    cabinet_inside_t *cabinet_inside[CABINET_NUM_MAX];
    int num;
}Cabinet_t;

// 所有设备数据、控制、配置 "基础拓扑模型"
typedef struct
{
	Cabinet_t cabinet_info;                 // 柜子
	
    struct Dev_METER_GRID_t meter_grid;     // 高压侧关口表
    struct Dev_METER_GRID_t meter_grid_lv;  // 低压侧关口表
    struct Dev_METER_PV_t meter_pv;         // 光伏表(交)
    struct Dev_PV_t pv;                     // 光伏逆变器(交)
    struct Dev_PCU_t pcu;                   // 充电桩
    struct Dev_METER_LOAD_t meter_load;     // 负载表
    struct Dev_METER_DG_t meter_dg;         // 柴发表

    struct Dev_DIDO_t dido;
    /*....*/
}dev_info_all_t;

typedef struct {
    dev_info_all_t *var;
    cabinet_inside_t **grp;
}ctrl_thread_var_t;

// 控制参数     数据特征:主动预设 主观影响计算逻辑的参数，改动参数后需重启控制器
typedef struct
{
    pcs_ctrl_var_t *var;
    // 关于归中值与其阈值 最优解为90 5, 归中值太高阈值太大将有过充风险 阈值太小系统过于敏感  SOC_RTM范围为:[SOC_min, SOC_RTM, SOC_max]
    // 由于要求直接设置光伏输出 不加入步进值 暂时取消此功能
    // double PV_attenuation;               // 光伏功率下调的衰减值  此参数由功率平衡权重计算
    // double PV_amplification;             // 光伏功率上调的增幅值  此参数由功率平衡权重计算
    int RTM_EN;                             // 回中使能 1:使能 0:失能 //特性
    enum MODE_MICROGRID mode_microgrid;     // 微网拓扑模式     0:禁用微网    1:微网直流并离网模式    2:微网交流并离网模式
    int en_diesel_generator;                // 使能柴发         0:失能   1:使能
    int en_photovoltaic;                    // 使能光伏         0:失能   1:使能
    int en_mains;                           // 使能市电         0:失能   1:使能
    int en_charging_pile;                   // 使能充电桩       0:失能   1:使能
    int en_esc;                             // 使能储能柜       0:失能   1:使能
    int en_sts;                             //  使能STS         0:失能   1:使能
    int en_icb;                             //  使能并网断路器   0:失能   1:使能
    int en_lcb;                             //  使能负载断路器   0:失能   1:使能
    int en_ats;                             //  使能ATS         0:失能   1:使能

    int en_dg_meter;                         //  使能柴发         0:失能   1:使能


}microgrid_cfg_t;

typedef struct
{
    enum ENERGY_DIRECTION plan_statu;       // ems_plan的策略  放电为 1 充电为 2 待机为 0
    _Atomic int Grid_offgrid;               // 控制并离网 1并网 0离网
    _Atomic int onoff;                      // 控制开关机 1开机 0关机

	double discharge_max_set;				// 输出功率 最大当前限制值(正)  // 动态参数  (多柜相加)
	double charge_max_set;				    // 输入功率 最大当前限制值(负)  // 动态参数
	double plan_set_power;					// 计划充放电功率
    STRATAGY_TYPE choose_func;              // 业务功能选择 当前预设为 0 削峰填谷 1动态增容 2光伏消纳 3应急备电
	double SOC_max;                         // SOC最大门限 ->缓冲
	double SOC_min;                         // SOC最小门限 ->缓冲
    enum EMS_CONTROL_MODE ControlMode;      // 工作模式 0 手动模式 1 自动模式
    int en_anti_reflux;                     // 是否使能防逆流
    double anti_reflux;                     // 防逆流参数 不可为负!!!若为负，本控制器直接写PCS功率为0防止出现意外!!! 防逆流阈值 (kw) 设置5时 在负载获取50kw功率时, PCS仅最大输出45 预留5为电网提供 作为负载变动缓冲区

	_Atomic double pcs_exp_power;           // PCS设置功率设置 总(所有柜的汇聚)
	double bms_exp_power;                   // bms期望功率 总(所有柜的汇聚)
    _Atomic double pv_exp_power;            // 光伏期望功率设置-交流测
    _Atomic int pv_exp_onoff;               // 光伏期望开关机-交流测
    double mppt_exp_power;                  // 光伏期望功率设置-直流侧 总(所有柜的汇聚)
    double pvMax;                           // 光伏输出最大功率，光伏系统功率上限(总光伏输出)
    int pv_km;                              // 光伏增长斜率，防止光伏突然起来对PCS造成冲击（交流侧）
    int pv_mode;                            // 光伏模式，0：功率，1：百分比
    int pv_isctrl;                          // 光伏是否可控，0：可控，1：不可控 (用于1.光伏不可控、2.光伏可控但无开关机状态反馈 -->跳过PV开关机检查) 默认：0
    int dead_night;                         // 黑夜死区
	double dischargeMaxPower; 			    // 输出功率 限制最大值(正)      // 静态参数 初始化固定（配置值）
	double chargeMaxPower; 			        // 输入功率 限制最大值(负)      // 静态参数 初始化固定
    // double SOC_RTM;                          // SOC_RTM_range 最大为 10; SOC_RTM = 100时 SOC_RTM_range 只能为 0;
    // SOC归中值设定 Return to median; 归中值不得超过SOC上限/下限 否则无效并被重置为默认90
    double SOCmaxReturnDiff;                // SOC 上限回差
    double SOCminReturnDiff;                // SOC 下限回差
    double SOC_max_combin, SOC_min_combin;  // SOC <并网> 最大充电/放电 上限/下限 百分比 归中范围不可大于此范围 例如当:SOC_max = 100 SOC_min = 10 SOC_RTM = 90
    double SOC_max_netdead, SOC_min_netdead;// SOC <离网> 最大充电/放电 上限/下限 百分比 归中范围不可大于此范围 例如当:SOC_max = 100 SOC_min = 10 SOC_RTM = 90
    double DemandErr;                       // 需量保护参数（暂时不用）
    int EnProtectTransf;                    // 是否使能变压器保护
    double Pmlmax;                          // 变压器容量
    int K1;                                 // 变压器需量控制系数
    double dg_rated_power;                  // 柴发额定容量
    double dg_boot_soc;                     // 柴发启动SOC阈值
    double SocAlarmThreshold;               // SOC预警值
    double DemandDiff;                      // 动态增容余量
    double PmlmaxDiff;                      // 需量回差       // TODO
    double DgDiff;                          // 柴发回差             // TODO
    int en_ac_d2c;                          // 使能交流 峰电-放转充 0:失能   1:使能
    int en_ac_c2d;                          // 使能交流 谷电-充转放 0:失能   1:使能
    bits cut_flag;                          // bit map  // 切换标识 0:无 1:强制切入本状态 --> 可在状态行为逻辑中强制置位目标状态的切换标识
    int action_timeout;                     // 动作超时时间
    int EnTraceLoad;                        // 负荷跟踪使能 高于防逆流优先级
    double TraceLoad;                       // 负荷跟踪参数
    int DG_cap_pro;                         // 柴发容量保护使能开关
    int EnProtectTrasLV;                    // 低压变压器保护
    int PLVmlmax;                           // 低压变压器容量
    double k4;                              // 低压需量控制系数
    int en_DOD;                             // DOD 保护使能开关
    int en_bms_power_limit;                 // bms功率限制使能开关
    double MaxDemand;                       // 最大需量
    int upper_limit;                        // 动态增容开始放电
    int lower_limit;                        // 动态增容开始充电
    int DemandStartHour;                    // 动态增容开始充电时
    int DemandStartMin;                     // 动态增容开始充电分
    int DemandEndHour;                      // 动态增容结束充电时
    int DemandEndMin;                       // 动态增容结束充电分
    int mppt_eq;                            // 光伏均衡功率调节的步进值kw
    int mppt_eq_tl;                         // 光伏平衡阶跃值总限制
    int mppt_eq_rt;                         // 单光伏配比均衡步进值
    int mpptnum;
    int sleep_pcs;                          // 调整PCS间隔
    int auto_off;                           // 是否使能自动关机
    int EnPvPrectrl;                        // 是否使能光伏精细化控制
    int singleV_sleep;                      // 单体电压延迟时间
    int volmax;
    int volmaxerr;
    int volmin;
    int volminerr;
    int EN_CELL_VOLT;
    int pcs_auto_turn;
    int pcs_auto_statu;     // 状态
    int pcs_auto_turn_off_time;
    double pcs_exp_power_actual;
    int Single_Cell_Vol_Threshold_Alarm; // SOC告警

}microgrid_ctrl_t;

typedef struct
{
    double pcs_power;                  // pcs总功率
    double pcs_repower;                // pcs总无功功率
    double pv_power;                   // pv总功率
    double pv_repower;                 // pv总无功功率
    double mppt_power;                 // mppt总功率
    double grid_power;                 // 电网表功率
    double grid_lv_appower;            // 电网表功率
    double grid_repower;               // 电网表无功功率
    double grid_appower;               // 电网表视在功率
    double load_power;                 // 负载表功率
    double dg_power;                   // 柴发表功率
    double dg_repower;                   // 柴发表功率
    double SOC_average;                // 多柜平均soc
    double SOC_ceiling;                // 多柜soc最大值
    double SOC_floor;                  // 多柜soc最小值

    int on_line;                       // LC是否在线
    int grid_statu;                    // 并网状态 1并网 0未知
    int offgrid_statu;                 // 离网状态 1离网 0未知
    int on_statu;                      // 开机状态 1开机 0未知
    int off_statu;                     // 关机状态 1关机 0未知
    int pv_on_statu;                   // pv开机状态 1开机 0未知
    int pv_off_statu;                  // pv关机状态 1关机 0未知
    _STATE_BATTERY battery_sta;        // 总的电池状态  所有平均soc
    int night_flag;
}microgrid_data_t;

typedef struct
{
    int lcb_abnormal;                            // 负载断路器反馈    0: 正常  1:合闸异常  2:分闸异常
    int icb_abnormal;                            // 并离网断路器反馈  0: 正常  1:合闸异常  2:分闸异常
    int DG_abnormal;                             // 柴发启动反馈      0: 正常  1:启动异常  2:停机异常

}microgrid_abnormal_t;

enum _ABNORMAL
{
    LCB_SIGN_ON,
    LCB_SIGN_OFF,
    ICB_SIGN_ON,
    ICB_SIGN_OFF,
    DG_SIGN_ON,
    DG_SIGN_OFF,
};
typedef enum _ABNORMAL ABNORMAL;
typedef struct 
{
    int code;
    char *msg;
} micro_abnormal_msg_t;

#define BIT_STATE_AWAIT 1                   // 待机
#define BIT_STATE_CONNECT_GRID 2            // 市电并网
#define BIT_STATE_OFF_GRID 3                // 离网
#define BIT_STATE_CF_CONNECT_GRID 4         // 柴发并网
#define BIT_STATE_INIT 5                    // 初始
#define BIT_STATE_ABNORMAL 6                // 异常状态
#define BIT_STATE_DEFAULT 7                 // 默认状态

/*微网状态机*/
enum _STATE_MICROGRID
{
    /*非状态 仅作返回值*/
    // _STATE_RESTRT = -2,         // 重启状态机
    // _STATE_NONE = -1,           // 空

    /*各状态*/
    STATE_AWAIT = 0,                // 待机
    STATE_CONNECT_GRID,             // 市电并网
    STATE_OFF_GRID,                 // 离网
    STATE_CF_CONNECT_GRID,          // 柴发并网
    STATE_INIT,                     // 初始
    STATE_ABNORMAL,                 // 异常状态
    STATE_DEFAULT,                  // 默认状态

    /*非状态 仅用注册数组大小*/
    _STATE_MAX,                 // 最大
};

extern const char state_string_enum_info[7][100];

typedef enum _STATE_MICROGRID RELEVANCE_STATE;
#define STATE_MAX _STATE_MAX;

struct STATE_INFO
{
    RELEVANCE_STATE (*handover_detect)(RELEVANCE_STATE state_self);             // 当前状态支持的切换场景 对应事件的识别以及退出处理
    int (*behaviour_func)(RELEVANCE_STATE state_self);                          // 当前状态行为 
    // RELEVANCE_STATE (*state_return)(RELEVANCE_STATE state_self);             // 当前状态退出  非0:执行错误  0:执行正确
    RELEVANCE_STATE (*init)(RELEVANCE_STATE last_state, RELEVANCE_STATE state); // 进入本状态初始化 
    RELEVANCE_STATE state_self;                                                 // 自身状态    初始化产生，勿要更改
    int action_step_idx;                                                        // 状态机执行初始化动作索引
};

typedef struct
{
    RELEVANCE_STATE major_state;            // 当前主状态
    int state_action_size;
    RELEVANCE_STATE last_state;             // 上一个状态
    RELEVANCE_STATE (*states_exit)(RELEVANCE_STATE last_state, RELEVANCE_STATE state); // 所有状态退出时统一行为
    struct STATE_INFO state[_STATE_MAX];    // "状态机"
} current_stat_t;

typedef struct
{
	current_stat_t ac_state;
	current_stat_t dc_state;
} state_machine_t;


typedef struct
{
	state_machine_t state_machine;

	dev_info_all_t dev_info_all;

	microgrid_cfg_t microgrid_cfg;
	microgrid_ctrl_t microgrid_ctrl;
	microgrid_data_t microgrid_data;

	void *var; //
} microgrid_t;

typedef struct {
    char *desc;
    void (*update_cb)(dev_info_all_t *var, int value);
    int update_param;   
    int (*condition_cb)(dev_info_all_t *var, int value);
    int condition_param; 
}micr_action_and_check_t;

typedef struct {
    bool (*func)(dev_info_all_t *var, int value, unsigned int pos);
    int param;   
}micr_condition_t;

typedef struct {
    char *desc;
    RELEVANCE_STATE state;
    unsigned int pos;
    LogicRelation relation;
    micr_condition_t conditions[CONDITION_NUM_MAX];
    bool (*check_condi_perp)(void);
}micr_condition_and_check_t;

// 通用光伏调节闭环算法 do input -> output 
struct Photovoltaic_info
{
    /*外部设定参数*/
    double output_power;    // 实际输出
    double k;               // 该光伏配比 精度: k < 1;  总 k = 1

    /*算法返回值*/
    double power_set;       // 算法给出的设定输出值
    /*内部处理*/
    double Sle;             // 0:光能不足，贫 1:光能富裕，余

};
struct Photovoltaic_power_adjust
{
    double exp_power;                   // 期望调节的目标输出功率
    double Step_value;                  // 单柜的最大功率跃进值
    double Pulse_peak;                  // 脉冲峰值功率 限制功率总跃进功率
    double Balanced_step;               // 均衡光伏的单个光伏单元步进功率


    struct Photovoltaic_info *info;     // 对象数组
    int num;                         // 需调节的总光伏设备数

};
int Photovoltaic_adjust_info_set_data(struct Photovoltaic_power_adjust *info, double output_power, double k, int n);
int Photovoltaic_adjust_init(struct Photovoltaic_power_adjust *info, double exp_power, double step_value, double pulse_peak, double Balanced_step, int num);
int Photovoltaic_regulation_algorithm(struct Photovoltaic_power_adjust *info);
int cab_pcs_dispower(double power);
int cab_pcs_chargpower(double dis_power, double charge_power);
int Multi_cabinet_power_distribution(double exp_power);
int Multi_cabinet_power_distribution_charge(double exp_power, double charge_max);
int Multi_cabinet_power_distribution_stewing(double exp_power);
int cabinet_mppt_and_bms_power_set(cabinet_inside_t *cab);
int cabinet_mppt_and_bms_power_set_dispower(cabinet_inside_t *cab);

extern struct UD_log *micro_log;

extern dev_info_all_t dev_info_all;
extern microgrid_ctrl_t microgrid_ctrl;
extern microgrid_cfg_t microgrid_cfg;
extern microgrid_data_t microgrid_data;
extern microgrid_abnormal_t microgrid_abnormal;
dev_info_all_t *get_dev_info_all_var(void);
microgrid_ctrl_t *get_microgrid_ctrl_var(void);
microgrid_cfg_t *get_microgrid_cfg_var(void);
microgrid_data_t *get_microgrid_data_var(void);
microgrid_abnormal_t *get_microgrid_adnormal_var(void);
void SocrearlyWarning(void);
int PCS_set_power(double power_exp, int flag);
int set_pcs_onoff(int flag);
int set_pcs_connect(int flag);
int MPPT_set_power(double exp_power, int flag);
int mppt_power_reset(cabinet_inside_t *cab);
int pcs_check_connect(int flag);
int pcs_stop();
int set_pcs_ctrl_dischargepower(cabinet_inside_t *cab, void *arg);
int set_pcs_ctrl_chargepower(cabinet_inside_t *cab, void *arg);
int dido_dg_ctrl_set(int set_value, int check_time_s);
int dido_set_lcb(int set_value, int flag);
int dido_set_icb(int set_value, int flag);
int set_dg_statu(int set_value, int flag);
int get_dg_statu();

int ph_set_onoff_callback(int onoff);
int ph_set_power_callback(double power);


void ac_cab_scale_calculate(void);
int traverse_cab_dev_func(int (*func)(cabinet_inside_t *cab));
int traverse_cab_dev_func_arg(int (*func)(cabinet_inside_t *cab, void *arg), void *arg);
int Relevant_data_refresh();
double homingAlgorithmSOC(double soc, double soc_min, double soc_max, double SOCReturnDiff, double discharging_power_max, double charging_power_max,int *RTM_EN);
int BMS_protect_to_ctrl_PCS(double SOC, double SOC_min, double SOC_max, double *pcs_out_max, double *pcs_out_min, double out_power_min_limit, double out_power_max_limit, enum ENERGY_DIRECTION flag);
double cabinet_bms_centering();
int cabinet_bms_protect();
int cabinet_pcs_exp_power_set(cabinet_inside_t *cab);
int cabinet_mppt_exp_power_set(cabinet_inside_t *cab);
int off_grid_mppt_exp_power_func(cabinet_inside_t *cab);
int set_cab_charge_max(cabinet_inside_t *cab, void *arg);
int set_all_pcs_onoff_tag_pcs_auto(int flag);
void stop_power_allocation();
double antiReflux_Reverse(double grid_check, double grid_power, double anti_reflux, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, int flag);
double antiReflux_TraceLoad(double grid_check, double grid_power, double anti_reflux, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, int flag);
double antiReflux(double grid_power, double anti_reflux, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, int flag);
double xl_antiReflux_Reverse(double grid_check,double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double xl_antiReflux_TraceLoad(double grid_check,double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double xl_antiReflux_Twin(double grid_check,double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double xl_antiReflux(double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double demand_antiReflux(double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double xl_LV_antiReflux(double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
double xl_LV_antiReflux_Twin(double grid_check,double grid_power, double Pmlmax, double filter, double pcs_max_output, double pcs_min_output, double pcs_output, double _Pmlmax, int flag);
int traverse_pcs_callback_double_set(struct _pcs_t *pcs, const char *tag, void*  value);
int traverse_pcs_callback_int_set(struct _pcs_t *pcs, const char *tag, void* value);
int traverse_pcs_callback_check_onoff(struct _pcs_t *pcs, const char *tag, void* val);
int traverse_pcs_callback_check_connect(struct _pcs_t *pcs, const char *tag, void* val);
int traverse_pcs(int (*func)(struct _pcs_t *pcs, const char *tag, void* value), const char *tag, void *value);
int traverse_mppt(int (*func)(struct _mppt_t *mppt, const char *tag, void* value), const char *tag, void *value);
enum _STATE_MICROGRID resolve_state();

int pcs_limit_reset(cabinet_inside_t *cab);
int set_value_check_value_int(int value_set, int value_check, const char *dev_name, const char *tagname_set, const char *tagname_get, int sleep_time, int overtime);
int set_value_check_value_double(double value_set, double value_check, const char *dev_name, const char *tagname_set, const char *tagname_get, int sleep_time, int overtime);
int check_connect();
int mppt_stop();
int get_now_plan_power();
int state_check_and_switch(current_stat_t *state_machine);
int state_switch(current_stat_t *state_machine, RELEVANCE_STATE next_state);
int state_machine_Init();
void *state_machine_pthread(void *args);

void dev_cfg_flush();
void microgrid_cfg_flush(pcs_ctrl_var_t *var);
int microgrid_load_device_info(proto_forward_t *var, Cabinet_t *_cabinet_info);

int is_time_in_range(int start_h, int start_m, int start_s, int end_h, int end_m, int end_s);
int start_ac_microgrid(void);
int MicrogridtopologyIni(pcs_ctrl_var_t *var);
int micro_dev_function(function_data *input, int input_num, function_data *output, int *output_num);

#endif

