#ifndef __COLLECTOR_API_H_
#define __COLLECTOR_API_H_
#include <string.h>
#include <syslog.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdbool.h>
#ifdef EN_EMS
#include "../ems/mqtt_north.h"
#include "../ems/slave_ems.h"
#endif
#include "../proto_forward.h"
#include "pub_fun.h"
typedef enum
{
    ALARM_STATUS_NO,   // 无告警 告警恢复
    ALARM_STATUS_TRIG, // 告警
} ALARM_STATUS;        // 告警状态

typedef enum
{
    POWERLIMITED,      // EMS限功率运行
    POWERREFLUX,       // EMS逆流运行
    SYSSTOPED,         // EMS切手动保护
    GTIDMETEROFFLINE1, // 电网电表离线
    // BMSMETERIFFLINE1,//储能电表离线
    ALARM_TYPE_MAX
} ALARM_TYPE; // 弹窗告警类型

typedef enum 
{
    PCS_CONNSTA_DISCONNECT,
    PCS_CONNSTA_CONNECT,
    PCS_CONNSTA_UNKNOW,
} PCS_CONNSTA_E;

typedef enum 
{
    EMS_SYSTEM_NORM,
    EMS_SYSTEM_EXCEPT,
} EMS_SYS_STATUS_E;

typedef enum 
{
    eLC_TYPE_LC,
    eLC_TYPE_VLC,
    eLC_TYPE_EMS,
} LC_TYPE;
// #define EN_EMS //编译时候关闭，为了代码提示临时开启
#ifdef EN_EMS
typedef struct lc_it
{
    char sn[32];
    char no[64];
    char name[64];
    int disabled;
    char ipaddr[20];
    slave_ems * slave;
    LC_TYPE type;
} lc_it;

typedef struct pcs_ctrl_var_s
{
    int second_period_timer;
    int chargeType;
    ALARM_STATUS alarm_status_list[ALARM_TYPE_MAX]; // 有些无法周期判断是否告警 通过设置此标志位置 作为check_alarm_t判断方式
    bool config_chaged;
    bool config_save;
    bool cabinet_save;
    bool restart_code;
    int reboot_code; // 1等待写入后重启 2立即重启
    int rx_sig; // 接收到一些终止信号

    int system_status; // 0正常 >0异常
    sem_t datachange_sem;
    sem_t rack_temp_sem;
    void *device_layer_ptr; // 数采的指针
    bool enable_ems;
    bool enable_group_ctrl; // 分组控制
    proto_forward_param_t param;
    int snapshoot_interval;
    int tou_max_num;
    int ch_broadcast_timeout;
    // int log_lv;
    int sample_rate;          // 采样率
    int history_data_rolling; // 历史数据滚动存储的时间，单位:小时
    int cabinet_cnt;          // 有几套柜子
    int pv_pcs_num;           // 光伏pcs数量

    char sn_str[SN_MAX_LEN];
    char proc_name[PROGRAM_NAME_LEN];

    north_mqtt_param mqttparam;
    bool north_mqtt_enable;
    void *north_mqtt_var;
    char *net_node;
    //
    int lc_list_len; // 当前配置了多个LC
    lc_it *lc_list;  // 当前配置LC的信息

    time_t power_down_time; // EMS掉电时间
    int db_update_interval; // 数据持久化更新频率
    //
    domain_list_t domain_list;
    int reflush_flag;
} pcs_ctrl_var_t;
#endif

#if EN_LC
typedef struct pcs_ctrl_var_s
{
    void *device_layer_ptr; // 数采的指针
    int sample_rate;        // 采样率
    int cabinet_cnt;        // 有几套柜子
    int history_data_rolling; // 历史数据滚动存储的时间，单位:小时
    char sn_str[SN_MAX_LEN];
    char proc_name[PROGRAM_NAME_LEN];
    char *net_node;
    int reboot_flag;
} pcs_ctrl_var_t;
#endif

#define tag_value tag_value_t

typedef void (*ems_data_cb_t)(char *nod, tag_value *data_value);
typedef void (*ems_data_par_cb)(char *nod, tag_value *data_value, void *par);

typedef struct ems_with_par_cb_s {
    void *par;
    ems_data_par_cb cb;
} ems_with_par_cb_s;
int collector_write_one_float_data(const char *nod, double write_val);
int collector_write_one_int_data(const char *nod, int write_val);

int collector_read_one_float_data(const char *nod, double *resp_val);
int collector_read_one_int_data(const char *nod, int *resp_val);

int collector_variant_monitor_add(pcs_ctrl_var_t *var, const char **node, size_t size, ems_data_cb_t tag_get_data_cb_t);
int collector_flush_variant_monitor_add(pcs_ctrl_var_t *var, const char **node, size_t size, ems_data_cb_t tag_get_data_cb_t);
int collector_variant_monitor_add_one(pcs_ctrl_var_t *var, char *node, ems_data_cb_t tag_get_data_cb_t);
int collector_variant_monitor_add_mul(pcs_ctrl_var_t *var, const char **node_temp, size_t size, ems_data_cb_t tag_get_data_cb_t, int cabinet_cnt);
int collector_ems_variant_monitor_add_mul(pcs_ctrl_var_t *var, const char **node_temp, size_t size, ems_data_cb_t tag_get_data_cb_t, int cabinet_cnt);
int collector_var_monitor_add_mul(pcs_ctrl_var_t *var, const char **node_temp, size_t size, ems_data_cb_t tag_get_data_cb_t, int cabinet_cnt, int type);
int set_sample_period(char *name, int sample_period);
bool check_nod_exist(const char *nod);
int collector_variant_monitor_add_one_with_par(pcs_ctrl_var_t *var, char *node, ems_data_par_cb cb, void *par, int type);// type:0->变化回调 1->刷新回调
pcs_ctrl_var_t *get_pcs_ctrl_var(void);
/*************************************************************************************/
void dev_set_dev_tag_float(const char* dev_id, const char* var_id, double val);

void dev_set_dev_tag_int(const char* dev_id, const char* var_id, int val);

int dev_get_dev_tag_int(const char* dev_id, const char* var_id);

double dev_get_dev_tag_float(const char* dev_id, const char* var_id);

int dev_get_nodeid_int(const char* nod_id);

int dev_get_dev_tag_float_with_result(const char *dev_id, const char *var_id, double *value);
int dev_get_dev_tag_int_with_result(const char* dev_id, const char* var_id,int *value);
/*********************************PCS操作方法,不同PCS操作方法不一样********************************************/

void def_set_pcs_power(const char* dev_id, float val);

void def_set_pcs_repower(const char* dev_id, float val);

void def_set_pcs_mode(const char* dev_id, int val);

void def_set_pcs_onoff(const char* dev_id, int val);

void dev_set_pcs_connect(const char* dev_id, PCS_CONNSTA_E val);

double def_get_pcs_power(const char* dev_id);

double def_get_pcs_repower(const char* dev_id);

int def_get_pcs_onoff(const char* dev_id);

int dev_get_pcs_connect(const char* dev_id);

int dev_get_pcs_mode(const char* dev_id);

int dev_get_function_int(const char* dev_id, const char* function, int* value);

int dev_get_function_double(const char* dev_id, const char* function,double* value);

int dev_set_function(const char* dev_id, const char* function, double value);

#endif /* __COLLECTOR_API_h */
