#ifndef __MAIN_H__
#define __MAIN_H__

#include <syslog.h>
#include "ipc_session.h"
#include "mqtt_session.h"
#include "lnxall_list.h"
#include "dy_utils/dy_common.h"
#include "dy_utils/dy_ipc.h"
#include "dy_utils/hash_intptr.h"
#include "dy_utils/modbus_utils.h"
#include "dy_utils/period_service.h"
#include "dy_utils/bitmap.h"
#include "sys/param.h"
#include "assert.h"
#include <lnxall_ubuslog.h>
#define GROUP_BMS_INDEX(var, grp_index, bms_index) (var->grp[grp_index].eng_ass_grp_cfg.bms_sn[bms_index])
// 调度器数据

#define ENG_ASS_SN_LEN_MAX SN_MAX_LEN
#define ENG_ASS_BMS_NUM_MAX 10
#define ENG_ASS_GRP_MAX 10
#define TAG_LEN_MAX 16
#define TAG_NAME_LEN_MAX 32
#define CURRENT_TAG_NUM 5
#define ENG_ASS_DATA_VALUE_INIT -1
#define ENG_ASS_DEFAULT_SERVICE "general"
#define ENG_ASS_SOFT_VER "1.0.0"
#define MQTT_NAME_LEN 64
#define MQTT_QOS_LEVLE0 0
#define KEEP_ALIVE_MAX  3600

typedef enum
{
    ENG_ASS_DEV_STA_UNKNOW = -1,
    ENG_ASS_DEV_STA_OFFLINE,
    ENG_ASS_DEV_STA_ONLINE,
} ENG_ASS_DEV_STA_E;

typedef enum
{
    ENG_ASS_PROTECT_FAULT_INIT = -1,
    ENG_ASS_PROTECT_FAULT_NONE = 0,
    ENG_ASS_PROTECT_FAULT_1,
    ENG_ASS_PROTECT_FAULT_2,
    ENG_ASS_PROTECT_FAULT_3,
} ENG_ASS_FAULT_LEVEL_E;

typedef enum
{
    ENG_ASS_PROTECT_LEVEL_INIT = -1,
    ENG_ASS_PROTECT_LEVEL_NONE = 0,
    ENG_ASS_PROTECT_LEVEL_1,
    ENG_ASS_PROTECT_LEVEL_2,
    ENG_ASS_PROTECT_LEVEL_3,
} ENG_ASS_PROTECT_LEVEL_E;

typedef enum
{
    E_TAG_INT,
    E_TAG_FLOAT
} tag_type_e;

// 组内控制寄存器
typedef struct
{
    // TODO
    int connect;
    int active_power;
    int last_active_power;
    int reactive_power;
    int run_state;
    int conn_high_power; // BMS上高压状态
    int switch_on_state; // 电操合闸状态
    int disconnect_v;//离网电压期望
    // 保护等级
    int protect_level;
    int relay;
    int pcs_remote;
    int wggl_power;//无功功率
    int last_wggl_power;
} eng_ass_grp_ctrl_t;

typedef struct hash_intptr hash_intptr_t;

typedef struct eng_ass_data_s
{
    //TODO
    //注意以下变量存储单位,按照原来pcs_dev_virtual存储
    int   pcs_fault;
    int   pcs_comm_fault;
    int   pcs_conn_fb_fault;
    int   pcs_run_fb_fault;
    float pcs_active_power;
    float pcs_reactive_power;
    int   pcs_connect_state; 
    int   pcs_conenable;   
    int   pcs_run_state;
    int   pcs_remote;
    int   meter_comm_fault;
    float meter_a_voltage;
    float meter_b_voltage;
    float meter_c_voltage;
    float meter_a_current;
    float meter_b_current;
    float meter_c_current;
    float meter_total_power;
    float meter_reactive_power;
    float meter_positive_energy;
    float meter_negtive_energy;
    int   bms_fault;
    int   bms_comm_fault;
    float bms_soc;
    int   bms_work_state;
    int   bms_cha_discha_state;
    float bms_total_voltage;
    float bms_total_current;
    float bms_avaiable_cha_curr;
    float bms_avaiable_disc_curr;
    int   bms_conn_high_power;   // BMS上高压状态
    int   bms_switch_on_state;  // 电操合闸状态
    int   protect_level;          //保护等级
    int   fault_level;            //故障等级
    int   on_service_state;           //投运状态
    int   expect_run_state;
    int   expect_power;//期望有功功率
    int   expect_wggl; //期望无功功率
    int   last_run_state;  //保留上一次设置的运行状态
    int   happen_state;  //触发过异常标志位
    int   last_ch_state; //上次充放电状态 1充电2放电 0默认值不用
    int   expect_relay_state;
    int   bms_relay_p;
    int   bms_relay_n;
    int   pcs_stop_flag;//停机状态
    int   pcs_run_flag;//运行状态
    int   pcs_standby_flag;  //待机状态
    double SOCMAX;
    double SOCMIN;
	double SINGLE_MAX;
    double SINGLE_MIN;
} eng_ass_data_t;

//设备状态
typedef struct
{
    ENG_ASS_DEV_STA_E pcs_online;
    ENG_ASS_DEV_STA_E meter_online;
    ENG_ASS_DEV_STA_E bms_online;
} eng_ass_dev_sta_t;

//组数据
typedef struct eng_ass_grp_data_s
{
    //TODO
    //注意以下变量存储单位,按照原来pcs_dev_virtual存储
    int   pcs_fault;
    float pcs_active_power;
    float pcs_reactive_power;
    int   pcs_connect_state; 
    int   pcs_conenable;   
    int   pcs_run_state;
    int   pcs_remote;
    int   pcs_conn_fb_fault;
    int   pcs_run_fb_fault;
    int   pcs_comm_fault;
    time_t last_conn_conflict_time;
    time_t last_run_conflict_time;
    float meter_a_voltage;
    float meter_b_voltage;
    float meter_c_voltage;
    float meter_a_current;
    float meter_b_current;
    float meter_c_current;
    float meter_total_power;
    float meter_reactive_power;
    float meter_positive_energy;
    float meter_negtive_energy;
    int   bms_fault;
    int   bms_comm_fault;
    float bms_soc;
    int   bms_work_state;
    int   bms_cha_discha_state;
    float bms_total_voltage;
    float bms_total_current;
    float bms_avaiable_cha_curr;
    float bms_avaiable_disc_curr;
    int   bms_conn_high_power;   // BMS上高压状态
    int   bms_switch_on_state;  // 电操合闸状态
    int   fault_level;          //故障等级
    int   bms_relay_p;
    int   bms_relay_n;
    int   pcs_stop_flag;//停机状态
    int   pcs_run_flag;//运行状态
    int   pcs_standby_flag;  //待机状态
    int   bms_under_vol_alarm;//欠压告警
    int   bms_over_vol_alarm;//过压告警
    int   char_cell_over_vol1_alarm;
	int   dischar_cell_under_vol1_alarm; 
	int   dischar_cell_overtmp1_alarm;
	int   dischar_cell_undertmp1_alarm;
	int   char_cell_overtmp1_alarm;
	int   char_cell_undertmp1_alarm;
    int   dischar_total_under_vol1_alarm;
	int   char_total_over_vol1_alarm;

	int   char_cell_over_vol2_alarm;
	int   dischar_cell_under_vol2_alarm;
	int   dischar_cell_overtmp2_alarm;
	int   dischar_cell_undertmp2_alarm;
	int   char_cell_overtmp2_alarm;
	int   char_cell_undertmp2_alarm;
    int   dischar_total_under_vol2_alarm;
	int   char_total_over_vol2_alarm;

	int   char_cell_over_vol3_alarm;
	int   dischar_cell_under_vol3_alarm;
	int   dischar_cell_overtmp3_alarm;
	int   dischar_cell_undertmp3_alarm;
	int   char_cell_overtmp3_alarm;
	int   char_cell_undertmp3_alarm;
    int   dischar_total_under_vol3_alarm;
	int   char_total_over_vol3_alarm;

    float bms_single_max;
	float bms_single_min;
    float bms_charge_current;  //充电电流
    float bms_discharge_current; //放电电流
    // int   bms_charge_alarm_state;//充电停止标志位
    // int   bms_discharge_alarm_state;//放电停止标志位
    int pcs_limit_power_run;//限功率运行
    int   empty_discharge;
    int   fully_charged;
    int disconnect_v;
    eng_ass_dev_sta_t dev_sta;  //设备状态
    int   bms_under_hold;//欠压保持标识，只有在电流方向切换时才会清除
    int   bms_over_hold;//过压保持标识，只有在电流方向切换时才会清除
    int   bms_char_hold_one;      //充电一级保持标识，降功率 50%
    int   bms_dischar_hold_one;   //放电一级保持标识，降功率 50%
    int   bms_char_hold_two;      //充电二级保持标识，只有在电流方向切换时才会清除     ，   功率0
    int   bms_dischar_hold_two;   //放电二级保持标识，只有在电流方向切换时才会清除，   功率0
    int   bms_char_hold_three;    //充电三级保持标识，只有在电流方向切换时才会清除，   功率0
    int   bms_dischar_hold_three; //放电三级保持标识，只有在电流方向切换时才会清除，   功率0

    //设备读取到数据时间
    time_t meter_recv_time;    
    time_t pcs_recv_time;
    time_t bms_recv_time;
} eng_ass_grp_data_t;

// 组数据
typedef struct eng_ass_grp_cfg_s
{
    // TODO
    char *meter_sn;
    char *pcs_sn;
    char *belong_gw;
    char *bms_sn[ENG_ASS_BMS_NUM_MAX];        // 储能可能多个
    char *bms_belong_gw[ENG_ASS_BMS_NUM_MAX]; // 储能可能多个
    // TODO 加载配置动态初始化:-1 0:
    ENG_ASS_DEV_STA_E meter_online;
    ENG_ASS_DEV_STA_E pcs_online;
    ENG_ASS_DEV_STA_E bms_online[ENG_ASS_BMS_NUM_MAX];
    uint32_t bms_dev_num;
    int scale_factor;
} eng_ass_grp_cfg_t;

typedef struct eng_ass_tag_desc_s
{
    void *p;  // 变量指针
    int type; // 数据类型
} eng_ass_tag_desc_t;

typedef struct eng_ass_grp_s
{
    eng_ass_grp_data_t eng_ass_grp_data;
    eng_ass_grp_ctrl_t eng_ass_grp_ctrl;
    eng_ass_grp_cfg_t eng_ass_grp_cfg;
    pthread_t action_thread;
    pthread_cond_t action_cond;
    pthread_mutex_t action_mutex;
} eng_ass_grp_t;

typedef struct  mqtt_info_s{
    char username[MQTT_NAME_LEN];
    char password[MQTT_NAME_LEN];
    char hostname[MQTT_NAME_LEN];
    unsigned short port;
}MQTT_INFO_T;

typedef enum run_mode_e{
    E_ONGW_MODE,     //本地接收，发送到本地     io与ems网关在一起
    E_ONIOTBOX_MODE //远端接收，ems本地执行    虚拟io与ems网关
}E_RUN_MODE;

typedef struct energy_var_s
{
    char module[64];                 //服务名称
    char sn_str[SN_MAX_LEN];          // 板子sn
    char eng_sn_str[SN_MAX_LEN];      // TODO 协调控制器自己的SN 需要订阅Set_rglt
    char vpcs_sn_str[SN_MAX_LEN];     // 兼容老接口
    char bmsmeter_sn_str[SN_MAX_LEN]; // TODO 发布电表SN为了,让平台端不改过度方案
    char emsctrl_sn_str[SN_MAX_LEN];
    char proc_name[PROGRAM_NAME_LEN];

    ipc_session_t *session;
    ipc_session_t *exsession;
    int calculate_timer;
    eng_ass_data_t *eng_ass_data;
    pthread_rwlock_t lock_calcu;
    pthread_t thread_calcu;
    // 数据
    //  eng_ass_grp_data_t *eng_ass_grp_data;
    //  eng_ass_grp_cfg_t *eng_ass_grp_cfg;
    eng_ass_dev_sta_t dev_sta;
    eng_ass_grp_t grp[ENG_ASS_GRP_MAX];
    void *module_item;
    MQTT_INFO_T mqttBroker;
    unsigned char runMode;
    int dev_online_timeout;
    // 配置
    int eng_ass_grp_num;
    int scale_factor_total_num;
    int power_assign_mode;
    hash_intptr_t *sub_gw_sn_map;
    // struct hash_intptr *tag_name_maps;  //记录tag ->  json key  给ems_ctrl 接口查表
    int ems_run_mode;//emsctrl 运行模式 0 手动模式， 1 自动模式
    int supportStandy;
} energy_var_t;

typedef int (*data_event_cb_t)(energy_var_t *var,void *param); 
typedef int (*alarm_event_cb_t)(energy_var_t *var,void *param); 

typedef struct
{
    char *name;
    char *alias;
    int (*init)(energy_var_t *var,void *param);
    void (*set_runmode)(energy_var_t *var,int mode); 
    void (*set_pcs_connect)(energy_var_t *var,int action); 
    void (*set_total_power)(energy_var_t *var,int power,int is_wggl); 
    void (*set_service_state)(energy_var_t *var,int action); 
    void (*set_bms_relay)(energy_var_t *var,int action);
    void (*clr_pcs_error)(energy_var_t *var);  
    void (*on_dev_data_updata)(energy_var_t *var,void *json_ptr,int grp_idx); 
    void (*set_data_event_cb)(energy_var_t *var,data_event_cb_t cb); 
    void (*set_alarm_event_cb)(energy_var_t *var,alarm_event_cb_t cb); 
}abstract_item_t;

#endif
