#ifndef __JSONCT_H__
#define __JSONCT_H__
#include "collector-api.h"
#include "open62541.h"
#include "deviceLayer.h"

#include "../common.h"
#include "pub_fun.h"
#define ALL_PLAN_FILE "/app/config/emms2_plan.json"
#define N_MQTT_NORTH_CFG_FILE "/app/config/north/mqtt_north_cfg.json"
/*-----------------------导出历史数据--------------------------------*/

#define HISTORY_DOC "/history/"
#define INDEX_LIST_NAME "index.list"
#define USE_PERCENT 90
#define DELETENUM 10
// #define MAKE_DOC_NAME(dist,a,b,c,d) sprintf(dist,"history-%d-%d-%d-%d/",a,b,c,d)
#define ONE_DAY (86400) //每次打包前一天+一分钟的数据
/*------------------------------------------------------------------*/
extern int g_reflush_all_plan;
#define MAX_DAY_YEAR 366
#define POWER_MAX_VAL UINT16_MAX
#define AGAINST_POWER_MAX 60
#define SOC_MAX_VAL 100
#define SECOND_TIME 1000
#define THREE_HUNDRED_MS 300
#define NUM_TOU_SEG_MAX 96
#define NUM_DEMAND_MAX 1
#define NUM_DEMAND_LIMITE_MAX 12
#define REBOOT_VALUE  0x5aa5
#define INVALID_REG_ADDR (0xffff)
#define DEFAULT_PCS_POWER 2000

#define _TO_STRING(a) #a
#define TO_STRING(a) _TO_STRING(a)

#define GET_JSON_DOUBLE(root, value_p, key)                                    \
    do                                                                               \
    {                                                                                \
        cJSON *__item = cJSON_GetObjectItem(root, key);                              \
        if (__item)                                                                  \
            memcpy((void *)&value_p, (void *)&__item->valuedouble, sizeof(value_p)); \
    } while(0)

#define GET_JSON_FLOAT(root, value_p, key)                                    \
    do                                                                               \
    {                                                                                \
        cJSON *__item = cJSON_GetObjectItem(root, key);                              \
        if (__item)                                                                  \
            value_p = __item->valuedouble;                                           \
    } while(0)


#define GET_JSON_INT(root, value_p, key)                                    \
    do                                                                            \
    {                                                                             \
        cJSON *__item = cJSON_GetObjectItem(root, key);                           \
        if (__item)                                                               \
            memcpy((void *)&value_p, (void *)&__item->valueint, sizeof(value_p)); \
    } while (0)

#define GET_JSON_STRING(root, value_p, key)       \
    do                                                  \
    {                                                   \
        cJSON *__item = cJSON_GetObjectItem(root, key); \
        if (__item)                                     \
        {                                               \
            if (__item->valuestring)                    \
                strcpy(value_p, __item->valuestring);   \
        }                                               \
    } while (0)


enum MODE_MICROGRID
{
    MODE_MICROGRID_NONE = 0,
    MODE_MICROGRID_DC,
    MODE_MICROGRID_AC,
    MODE_MAX
};

typedef enum EMS_CONTROL_MODE
{
    EMS_MANUAL_MODE = 0,
    EMS_AUTO_MODE = 1,
    EMS_REMOTE_MODE = 2,
    EMS_SUM_SYS_MODE = 3,
}EMS_CONTROL_MODE;

typedef enum  //0:削峰填谷模式 1:变压器增容 2:光储联动 3:应急备电
{
    STRATAGY_TYPE_PERIOD_CTRL,//削峰填谷模式
    STRATAGY_TYPE_DEMAND_FIXED,//固定需量模式(以后改为变压器增容)
    STRATAGY_TYPE_NONE,        //无
    STRATAGY_TYPE_PV_STORAGE, //光储联动
    STRATAGY_TYPE_STANDBY, // 备电
    STRATAGY_TYPE_MAX
} STRATAGY_TYPE;

typedef struct 
{
    char  StHour;
    char  StMin;
    char  EnHour;
    char  EnMin;
    int   Power;
    int   RePower;
    int   SocUp;
    int   SocLower;
}tou_seg_t;

typedef struct 
{
    int  StHour;
    int  StMin;
    int  EnHour;
    int  EnMin;
}demand_seg_t;

typedef struct 
{
    int demand_threshold[NUM_DEMAND_LIMITE_MAX];
    int charge_startpower;
    int discharge_threshold;
    demand_seg_t tou_seg[NUM_DEMAND_MAX];
}demand_param_t;

typedef struct pcs_cfg_s
{
    int EnDraughtFanFlowPower;
    int DraughtFanFlowPowerThreShold; 
    int EnDraughtFanFlowTem;  
    int DraughtFanFlowTemThreShold; 
    int DeadTime;
    
    int EnTraceLoad;       //使能负荷跟踪
    int EnProtectReverse;   //使能逆流保护
    int ProtectReverseWin;   //逆流滑动窗口
    int DemandWin;   //需量滑动窗口
    int EnProtectTransf;    //使能变压器保护
    int EnProtectDOD;       //使能BMS SOC监控
    int EnBmsAlarm;        //使能BMS 报警后联动
    int ControlMode;   //运行模式 远程本地模式
    int EnIoProtect;  
    int PcsAutoTurn;
    int PcsAutoTurnOffTime;

    int EnPcsRpComp; //使能PCS无功补偿
    float PcsPowerFactor; //PCS功率因数设置

    int PackAlarmLimitTemp;//电池包消防告警温度
    int WorkSamplePeriod;
    int IdleSamplePeriod;
    int MaxDemand;
    int EnableAutoCool;
    int En_SelfLoopDiff;
    int StartSelfLoopDiff;
    int EndSelfLoopDiff;
    int AirCondDelayTime;
    int EnableAirCond;
    int AirCondAheadTime;
    // int BeforeWorkTime;
    int PvMaxPower;
    int WStartHot;
    int WEndHot;
    int WStartCool;
    int WEndCool;
    int SStartHot;
    int SEndHot;
    int SStartCool;
    int SEndCool;
    // int PStartHot;
    // int PEndHot;
    // int PStartCool;
    // int PEndCool;

    int WDistHot;
    int WDistCool;
    int SDistHot;
    int SDistCool;
    // int PDistHot;
    // int PDistCool;
    int HeatCtrCycle;      //  热管理控制周期
    
    int Pmlmax;          //// 最大容量，用于需量跟踪   
    int K1;                 //     需量控制系数

    int K2;                 // 放电负载跟踪系数       
    float SOCmax;           //// soc最大充电阈值     
    float SOCmin;           //// soc放电最小阈值     
    int Pset;               //// 电网供电功率下限
    // int Perr;               //// 电网供电功率下限误差
    // int PchaMax;          //// 充电最大值，yut需量控制中pcs充电最大功率    
    // int PDiscMax;         //// 放电最大值, yut需量控制中pcs放电最大功率     
    int cab_power;            //储能最大充放功率,用于取代上面的参数  也是额定功率
    int cab_capacity;       //额定容量
    int Adjpreriod;         ////调整周期
    int tempThreshold;        //// 温度阈值,高于则温度告警
    int loadTrackingLimit; //期望值作为最大值的限制
    int numOfPcs;  //PCS组数
    int StratagyType; //策略
    int meter_invert; //电表取反
    int en_bms_power_limit; //使能BMS功率限制
    int EnProtectTrasLV;
    int PLVmlmax;
    int K3;         //多站点分配系数
    int K4;
    float SingleMaxVoltage; 
    float SingleMinVoltage; 
    float SingleMaxVoltageErr;
    float SingleMinVoltageErr;
    float SOCmaxErr;
    float SOCminErr;
    int EnCellVoltProtect;
    int EnDataCollect;
    
    int EnSTS;
    int EnICB;
    int EnLCB;
    int EnATS;

    int EnPhotovoltaic;
    int SOCmaxNetDead;
    int SOCminNetDead;
    int SOCmaxNet;
    int SOCminNet;
    int chargeMaxPower;
    int dischargeThreshold;
    int DGBootSoc;      //柴发启动时SOC
    int DGRatedPower;   //柴发额定功率
    int DG_Capacity_protection;  // 柴发容量保护使能开关
    int SocAlarmThreshold;   //SOC告警阈值
    //int en_ac_d2c;
    //int en_ac_c2d;
    int pv_km;
    int pv_mode;
    int dead_night;
    int pv_isctrl;
    int EnPvPrectrl;
    float DgDiff;
    int action_timeout;
    int DemandMargin;     // 需量余量
    int DynamicAugmentation;
    int g100Enable;             // g100 使能
    int g100UnlockTime;         // g100 解锁时间
    int g100LockMaxCount;       // g100 月内解锁最大次数
    int g100BackflowCount10Min; // g100 10分钟允许异常次数
    int g100BackflowCountDay;   // g100 日允许异常次数
    int g100BackflowLimit;      // g100 逆流限值
    int g100BackflowSec;        // g100 逆流滤波时间
    int g100BackflowLockTime;   // g100 逆流锁定时间
    int g100OverloadLimit;      // g100 过载限值
    int g100OverloadSec;        // g100 过载滤波时间
    int g100OverloadLockTime;   // g100 过载锁定时间
    int Accident_en;
    int Accident_tgi;
    float Mppt_eq;
    float Mppt_eq_tl;
    float Mppt_eq_rt;
    int EnSwD2C;
    int EnSwC2D;
    int Installedcab_coeff;
    int SingleVoltageTime;
    int micro_check; //微网检测 1有效
    long udlog;
    demand_param_t demand_param;
    tou_seg_t tou[NUM_TOU_SEG_MAX];
} usercfg_variant_t;

typedef enum CAB_TYPE_T
{
    CAB_TYPE_SINGLE,
    CAB_TYPE_MASTER,
    CAB_TYPE_SLAVE,   
} CAB_TYPE;

typedef enum MS_MODE_ENUM
{
    MS_MODE_STD,//标准主从
    MS_MODE_DC,//直流柜主从
    MS_MODE_MAX,   
} MS_MODE_ENUM;

typedef struct cabinet_info_tm
{
    char cab_id[256];
    char cnt_id[64];    // 高压侧所用并网点ID
    char cnt_id_l[64];  // 低压侧所用并网点ID
    char name[128];
    //int cab_type;  //单柜不需要
    char cab_location[128];
    int cab_capacity;
    int cab_power;
    int pack_temp_point;
    char cab_time[128];
    char cab_local[128];
    char cab_station_name[128];
    int en_virtual_meter;
    char tenant_id[128];
    int en_ems_cloud; //使能EMS云
    int en_mqtt_dp; //使能EMMS2
    int en_mqtt_emms2; //使能EMMS2
    int en_mqtt_emms2_write;
    int en_mqtt_stactrl; //使能站控mqtt
    int en_mqtt_stactrl_write; 
    int en_north_mqtt;  //使能标准北向
    int en_custom_mqtt; //使能定制北向
    UA_NodeId cabinet_id;
    int en_lc;
    int en_lc_ctrl;
    int ctrl_mode;
    enum MODE_MICROGRID mode_microgrid;
    int en_diesel_generator;
    int en_photovoltaic;
    int en_mains;
    int en_charging_pile;
    int en_esc;
    int en_sts;
    int en_icb;
    int en_lcb;
    int en_ats;
    int ms_mode;//主从模式:0-标准主从模式，1-直流柜模式，使用枚举MS_MODE_ENUM
    int is_slave;//非0为从机
}cabinet_info_t;

typedef struct cabinet_info_tm_tab
{
    char *cab_key;
    char *cab_show_name;
    int  cab_member_ofs;
    char *cab_type;
}cabinet_info_tab_t;

typedef struct 
{
    char *nod;
    int member_ofs; 
    int data_type;//数值类型
}ems_cfg_info_t;



typedef struct 
{
    int year;
    int mounth;
    int date;
    tou_seg_t schedule[NUM_TOU_SEG_MAX];
}all_plan; //计划

int load_ems_user_cfg(usercfg_variant_t *pcfg);

int load_ems_sys_cfg(usercfg_variant_t *pcfg);

int save_ems_user_cfg(usercfg_variant_t *pcfg);

int get_current_plan(usercfg_variant_t *pcfg, int *power, int *repower, int *socup, int *soclower);

void check_plan_soc_suitable(usercfg_variant_t *pcfg);

int load_cabinet_info_cfg(cabinet_info_t *pcfg);

char *create_md_server_tag_addr(ems_base_variant_t **tags, size_t tags_size);
char *create_modbus_server_template(ems_base_variant_t **tags, size_t tags_size);

char* create_ems_device(char *tem_file_name);

int get_demand_plan(usercfg_variant_t *pcfg);
void reflush_other_data_to_usercfg(usercfg_variant_t *pcfg);

int write_cabinet_info_file(cabinet_info_t *pcfg, const char *filepwd);
void read_cabinet_info_by_name(char *name ,void *value);
int cabinet_info_cmp_by_name(char *name, void *value, int *ok);
void write_cabinet_info_by_name(char *name ,void *value);
void add_systrm_info(UA_SERVER_PARAM *ua_param);
extern usercfg_variant_t g_usercfg_variant;
extern cabinet_info_t cabinet_info;
cabinet_info_t *get_cabinet_info();
// cJSON * json_parse_string_with_comments(char *string)
void export_history_init(cabinet_info_t *pcfg);

void save_all_plan_to_file(cJSON *plan);
int parse_all_plan(cJSON *messages);
void get_all_plan_from_file();

int check_to_plan_time(usercfg_variant_t *pcfg,int time,float powernow);
unsigned int get_seconds_of_today(void) ;
int load_lc_list(void);
int deleteDirectory(const char *path);
#endif
