#ifndef __UPS_H__
#define __UPS_H__
#include <stdint.h>

#define CMD_MAX_REG_SUM 30

typedef enum ups_data_t
{
    UPS_DATA_FLOAT = 0,
    UPS_DATA_BIT,
    UPS_DATA_MAX
} ups_data_t;

typedef struct ups_up_info_t
{
    char *cmd;
    ups_data_t type;
    int pos;
    int bit_pos;
} ups_up_info_t;

typedef struct ups_down_info_t
{
    char *cmd;
    int need_par;
} ups_down_info_t;


typedef struct ups_data
{
    ups_data_t type;
    union data
    {
        int _int; // UPS_DATA_BIT会被解析成int
        double _float;
        uint8_t _bits[9];
    } data;
} ups_data;

typedef struct ups_hd_t ups_hd_t;
typedef struct ups_if
{
    int (*connect)(ups_hd_t *hd);
    int (*tx)(ups_hd_t *hd, const void *buff, uint32_t len);
    int (*rx)(ups_hd_t *hd, void *buff, uint32_t max_len);
    int (*flush)(ups_hd_t *hd);
    int (*dis_connect)(ups_hd_t *hd);
    int (*free)(ups_hd_t *hd);
} ups_if;

struct ups_hd_t
{
    char name[32];
    int fd;
    int error_recovery;
    ups_if *if_funs;
    void *data;
    uint32_t read_time_out;
    uint32_t interval;
};

//
ups_data_t analysis_ups_type(char *addr);
ups_hd_t *new_ups_uart(char *dev, int baud, uint8_t data_bit, uint8_t stop_bit, char parity);
int ups_set_name(ups_hd_t *hd, char *new_name);
int ups_connect(ups_hd_t *hd);
int ups_dis_connect(ups_hd_t *hd);
int ups_free(ups_hd_t *hd);
int ups_set_time(ups_hd_t *hd, uint32_t timeout_ms, uint32_t interval);
int ups_read(ups_hd_t *hd, const char *cmd, void *buff, int buff_len);
int ups_write(ups_hd_t *hd, const char *cmd);
#endif