#include "data_real_time.h"
#include "data_telemet_common.h"
#include "head.h"
#include "bsp_type.h"

uint8_t g_yx_total_count = 0;

// 遥测显示数组定义
REAL_OPTTypeDef Telemet_opt[SUBMENU_TELEMET_NUM] = {
    {0, "母线侧Ua:             ", "V ", 2, 220.01},
    {1, "母线侧Ua:             ", "° ", 2, 360.00},
    {2, "母线侧Ub:             ", "V ", 2, 220.02},
    {3, "母线侧Ub:             ", "° ", 2, 360.00},
    {4, "母线侧Uc:             ", "V ", 2, 221.03},
    {5, "母线侧Uc:             ", "° ", 2, 360.00},
    {6, "母线侧Uab:            ", "V ", 2, 380.01},
    {7, "母线侧Uab:            ", "° ", 2, 360.00},

    {8, "母线侧Ubc:            ", "V ", 2, 381.02},
    {9, "母线侧Ubc:            ", "° ", 2, 360.00},
    {10, "母线侧Uca:            ", "V ", 2, 380.03},
    {11, "母线侧Uca:            ", "° ", 2, 360.00},
    {12, "母线侧U0:            ", "V ", 2, 381.02},
    {13, "母线侧U0:            ", "° ", 2, 360.00},
    {14, "母线侧Us:            ", "V ", 2, 380.03},
    {15, " ",                     " ", 2, 0.0},

    {16, "线路侧Ua:             ", "V ", 2, 220.01},
    {17, "线路侧Ua:             ", "° ", 2, 360.00},
    {18, "线路侧Ub:             ", "V ", 2, 220.02},
    {19, "线路侧Ub:             ", "° ", 2, 360.00},
    {20, "线路侧Uc:             ", "V ", 2, 221.03},
    {21, "线路侧Uc:             ", "° ", 2, 360.00},
    {22, "线路侧Uab:            ", "V ", 2, 380.01},
    {23, "线路侧Uab:            ", "° ", 2, 360.00},

    {24, "线路侧Ubc:            ", "V ", 2, 381.02},
    {25, "线路侧Ubc:            ", "° ", 2, 360.00},
    {26, "线路侧Uca:            ", "V ", 2, 380.03},
    {27, "线路侧Uca:            ", "° ", 2, 360.00},
    {28, "线路侧U0:            ", "V ", 2, 381.02},
    {29, "线路侧U0:            ", "° ", 2, 360.00},
    {30, "线路侧Us:            ", "V ", 2, 380.03},
    {31, " ",                     " ", 2, 0.0},

    {32, "保护电流Ia:         ", "A ", 3, 5.001},
    {33, "保护电流Ia:         ", "° ", 2, 360.00},
    {34, "保护电流Ib:         ", "A ", 3, 3.002},
    {35, "保护电流Ib:         ", "° ", 2, 360.00},
    {36, "保护电流Ic:         ", "A ", 3, 5.003},
    {37, "保护电流Ic:         ", "° ", 2, 360.00},
    {38, "保护电流I0:         ", "A ", 3, 2.001},
    {39, "保护电流I0:         ", "° ", 2, 360.00},

    {40, "测量电流Ia:         ", "A ", 3, 5.001},
    {41, "测量电流Ia:         ", "° ", 2, 360.00},
    {42, "测量电流Ib:         ", "A ", 3, 3.002},
    {43, "测量电流Ib:         ", "° ", 2, 360.00},
    {44, "测量电流Ic:         ", "A ", 3, 5.003},
    {45, "测量电流Ic:         ", "° ", 2, 360.00},
    {46, "P:                   ", "W ", 2, 550.01},
    {47, "Q:                   ", "Var", 2, 1100.01},

    {48, "S:                   ", "VA", 2, 1100.01},
    {49, "COS:                 ", "   ", 3, 60},
    {50, "F1:                  ", "Hz ", 2, 50.02},
    {51, "F2:                 ", "Hz ", 2, 50.02},
    {52, "Temperature:        ", "℃", 1, 1100.01},
    {53, "DC1:                 ", "V  ", 3, 12.05},
    {54, "母线侧正序:            ", "V ", 2, 220.00},
    {55, "母线侧负序:            ", "V ", 2, 220.00},
    {56, "线路侧正序:            ", "V ", 2, 220.00},
    {57, "线路侧负序:            ", "V ", 2, 220.00},
};

// 遥信显示数组定义
YX_OPTTypeDef Telesignal_opt[SUBMENU_TELESIGMAL_NUM]={
    {0,  "开关合位:       ","   " , 1},
    {1,  "开关分位:       ","   "},
    {2,  "地刀位置:       ","   "},
    {3,  "停用重合闸:     ","   "},
    {4,  "已储能:         ","   "},
    {5,  "常规保护:       ","   "},
    {6,  "自动化控制:     ","   "},
    {4,  "智能分布式:     ","   "},
    {8,  "停用自动解列:   ","   "},
    {9,  "手动复归:       ","   "},
    {10, "隔离刀位置:     ","   "},
    {11, "远方信号:       ","   "},
    {12, "非电量1:        ","   "},
    {13, "非电量2:        ","   "},
    {14, "非电量3:        ","   "},
    {15, "非电量4:        ","   "},
    {16, "非电量5:        ","   "},
    {17, "非电量5:        ","   "},
    {18, "开入量19:       ","   "},
    {19, "开入量20:       ","   "},
    {20, "开入量21:       ","   "},
    {21, "开入量22:       ","   "},
    {22, "开入量23:       ","   "},
    {23, "检修压板:       ","   "},
    {24, "其他 :       ","   "},
    {25, "其他 :       ","   "},
    {26, "其他 :       ","   "},
    {27, "其他 :       ","   "},
    {28, "其他 :       ","   "},
    {29, "其他 :       ","   "},
    {30, "其他 :       ","   "},
};

Para_OPTTypeDef  Remote_ctrl_opt[SUBMENU_REMOTCRTL_NUM]={
//序号,名称,单位,默认值,最大,最小,小数  10:表示非数值参数,非数值项索引

    {0,  "保护出口合闸    "," ",  0,       1   ,0,10,OPT_YXSTA},
    {1,  "保护出口分闸    "," ",  0,       1   ,0,10,OPT_YXSTA},
    {2,  "远方出口合闸    "," ",  0,       1   ,0,10,OPT_YXSTA},
    {3,  "远方出口分闸    "," ",  0,       1   ,0,10,OPT_YXSTA},
    {4,  "装置故障告警    "," ",  0,  1   ,0,10,OPT_YXSTA},
    {5,  "故障闭锁            "," ",  0,  1   ,0,10,OPT_YXSTA},
    {6,  "开出07 ", " ",  0,  1   ,0,10,OPT_YXSTA},
    {7,  "开出08 ", " ",  0,  1   ,0,10,OPT_YXSTA},
    {8,  "开出09 ", " ",  0,  1   ,0,10,OPT_YXSTA},
};

/**
 * @brief          获取遥测的角度
 * @param[in/out]  {int32_t} sw 开关号
 * @param[in/out]  {uint16_t} _ac_index 下标
 * @return         * float
 * @retval
 *
 * @warning
 * @note
 */
static float idio_get_angle_yc(int32_t sw, uint16_t _ac_index)
{
    float value = 0;
    data_bool_t bconvert = false;

    if (_ac_index > UI_NUM || sw > SWITCH_NUM_MAX)
    {
        rt_kprintf("液晶遥测数据索引错误!\r\n");
        return value;
    }

    if (sw == 0) // 公共遥测
    {
        if (_ac_index < PUB_AC_NUM_ALL)
        {
            if (pRunSet->bTT_RET_ZERO)
            {
                if (abs(g_sw_pub.ac_in[_ac_index]) > g_unit[g_pub_ac_desc[_ac_index].unit].zero)
                {
                    value = (float)(g_ui[_ac_index].p / 65536.0);
                }
                else
                {
                    value = 0;
                }
            }
            else
            {
                value = (float)(g_sw_pub.ac_in[_ac_index] / 65536.0);
            }
        }
        else
        {
            return 0; // 参数错误直接返回0
        }
    }
    else // 开关遥测
    {
        int index_begin;
        index_begin = UI_SW_INDEX_BEGIN(sw - 1);
        if (_ac_index < SW_AC_NUM_ALL)
        {
            if (pRunSet->bTT_RET_ZERO)
            {
                if (abs(g_sw[sw - 1].ac_in[_ac_index]) > g_unit[g_sw_ac_desc[_ac_index].unit].zero)
                {
                    value = (float)(g_ui[index_begin + _ac_index].p / 65536.0);
                }
                else
                {
                    value = 0;
                }
            }
            else
            {
                value = (float)(g_ui[index_begin + _ac_index].p / 65536.0);
            }
        }
        else
        {
            return 0; // 参数错误直接返回0
        }
    }
}


/**
 * @brief           获取并更新遥信数据
 * @return         * void 
 * @retval         
 * 
 * @warning        
 * @note           参考原有GetandChange_disp_yx函数实现
 */
void data_real_time_get_yx_data(void)
{
    static struct equ_config_di *ecd;
    int num = 0, g_sw_num = 0;
    u8 stu_f;

    g_sw_num = g_equ_config->di_num;

#if (0)
    if (g_sw_num > PUB_DI_NUM)
        g_sw_num = PUB_DI_NUM;
#endif

    stu_f = 0;
    // printf("%s g_equ_config->di_num = %d\n", __FUNCTION__,g_equ_config->di_num);
    for (num = 0; num < g_sw_num; num++)
    {

        if ((short)g_equ_config_di[num].type != INDEX_INVALLID)
        {
            ecd = &g_equ_config_di[num];
            stu_f = dido_di_is_on(ecd->slot, ecd->index);
            Telesignal_opt[num].valu = stu_f;
            Telesignal_opt[num].name = &ecd->name[0];
            if (stu_f < 2)
                Telesignal_opt[num].sta = Non_Numeric[OPT_YXSTA].opt[stu_f];
        }
        else
        {
            Telesignal_opt[num].name = Non_Numeric[OPT_YXSTA].opt[2];
            Telesignal_opt[num].sta = "";
        }
    }
    g_yx_total_count = g_sw_num; // 更新遥信总数
}

/**
 * @brief           获取并更新遥测数据
 * @param[in]      {GET_TYPE} type 遥测类型：TYPE_YCDISPLY_PRIMARY(一次值) / TYPE_YCDISPLY_SECONDY(二次值)
 * @return         * void 
 * @retval         
 * 
 * @warning        
 * @note           参考原有Get_pageyc_data函数实现
 *                 使用公共遥测取值接口data_telemet_get_value()替代本地yc_display_handle()
 */
void data_real_time_get_yc_data(GET_TYPE type)
{
    // 母线侧
    Telemet_opt[0].valu = data_telemet_get_value(0, PUB_AC_UA1, type);
    Telemet_opt[1].valu = idio_get_angle_yc(0, PUB_AC_UA1);
    Telemet_opt[2].valu = data_telemet_get_value(0, PUB_AC_UB1, type);
    Telemet_opt[3].valu = idio_get_angle_yc(0, PUB_AC_UB1);
    Telemet_opt[4].valu = data_telemet_get_value(0, PUB_AC_UC1, type);
    Telemet_opt[5].valu = idio_get_angle_yc(0, PUB_AC_UC1);
    Telemet_opt[6].valu = data_telemet_get_value(0, PUB_AC_UAB1, type);
    Telemet_opt[7].valu = idio_get_angle_yc(0, PUB_AC_UAB1);
    Telemet_opt[8].valu = data_telemet_get_value(0, PUB_AC_UBC1, type);
    Telemet_opt[9].valu = idio_get_angle_yc(0, PUB_AC_UBC1);
    Telemet_opt[10].valu = data_telemet_get_value(0, PUB_AC_UCA1, type);
    Telemet_opt[11].valu = idio_get_angle_yc(0, PUB_AC_UCA1);
    Telemet_opt[12].valu = data_telemet_get_value(0, PUB_AC_U01, type);
    Telemet_opt[13].valu = idio_get_angle_yc(0, PUB_AC_U01);
    Telemet_opt[14].valu = data_telemet_get_value(0, PUB_AC_US1, type);

    // 线路
    Telemet_opt[16].valu = data_telemet_get_value(0, PUB_AC_UA2, type);
    Telemet_opt[17].valu = idio_get_angle_yc(0, PUB_AC_UA2);
    Telemet_opt[18].valu = data_telemet_get_value(0, PUB_AC_UB2, type);
    Telemet_opt[19].valu = idio_get_angle_yc(0, PUB_AC_UB2);
    Telemet_opt[20].valu = data_telemet_get_value(0, PUB_AC_UC2, type);
    Telemet_opt[21].valu = idio_get_angle_yc(0, PUB_AC_UC2);
    Telemet_opt[22].valu = data_telemet_get_value(0, PUB_AC_UAB2, type);
    Telemet_opt[23].valu = idio_get_angle_yc(0, PUB_AC_UAB2);
    Telemet_opt[24].valu = data_telemet_get_value(0, PUB_AC_UBC2, type);
    Telemet_opt[25].valu = idio_get_angle_yc(0, PUB_AC_UBC2);
    Telemet_opt[26].valu = data_telemet_get_value(0, PUB_AC_UCA2, type);
    Telemet_opt[27].valu = idio_get_angle_yc(0, PUB_AC_UCA2);
    Telemet_opt[28].valu = data_telemet_get_value(0, PUB_AC_U02, type);
    Telemet_opt[29].valu = idio_get_angle_yc(0, PUB_AC_U02);
    Telemet_opt[30].valu = data_telemet_get_value(0, PUB_AC_US2, type);

    // 保护电流
    Telemet_opt[32].valu = data_telemet_get_value(1, SW_AC_IA, type);
    Telemet_opt[33].valu = idio_get_angle_yc(1, SW_AC_IA);
    Telemet_opt[34].valu = data_telemet_get_value(1, SW_AC_IB, type);
    Telemet_opt[35].valu = idio_get_angle_yc(1, SW_AC_IB);
    Telemet_opt[36].valu = data_telemet_get_value(1, SW_AC_IC, type);
    Telemet_opt[37].valu = idio_get_angle_yc(1, SW_AC_IC);
    Telemet_opt[38].valu = data_telemet_get_value(1, SW_AC_I0, type);
    Telemet_opt[39].valu = idio_get_angle_yc(1, SW_AC_I0);

    // 测量电流
    Telemet_opt[40].valu = data_telemet_get_value(1, SW_AC_IA, type);
    Telemet_opt[41].valu = idio_get_angle_yc(1, SW_AC_IA);
    Telemet_opt[42].valu = data_telemet_get_value(1, SW_AC_IB, type);
    Telemet_opt[43].valu = idio_get_angle_yc(1, SW_AC_IB);
    Telemet_opt[44].valu = data_telemet_get_value(1, SW_AC_IC, type);
    Telemet_opt[45].valu = idio_get_angle_yc(1, SW_AC_IC);

    // 功率等参数
    Telemet_opt[46].valu = data_telemet_get_value(1, SW_AC_IN_P, type);
    Telemet_opt[47].valu = data_telemet_get_value(1, SW_AC_IN_Q, type);
    #ifdef FUN_YC_POWER_S
    Telemet_opt[48].valu = data_telemet_get_value(1, SW_AC_IN_S, type);
    #endif    
    Telemet_opt[49].valu = data_telemet_get_value(1, SW_AC_IN_COS, type);
    Telemet_opt[50].valu = data_telemet_get_value(0, PUB_AC_IN_F1, type);
    Telemet_opt[51].valu = data_telemet_get_value(0, PUB_AC_IN_F2, type);
    Telemet_opt[52].valu = data_telemet_get_value(0, PUB_AC_IN_TEMP, type);
    Telemet_opt[53].valu = data_telemet_get_value(0, PUB_AC_IN_UZ1, type);
    // Telemet_opt[54].valu = data_telemet_get_value(0, PUB_AC_UPS1, type); // TODO 暂无
    // Telemet_opt[55].valu = data_telemet_get_value(0, PUB_AC_UNS1, type);
    // Telemet_opt[56].valu = data_telemet_get_value(0, PUB_AC_UPS2, type);
    // Telemet_opt[57].valu = data_telemet_get_value(0, PUB_AC_UNS2, type);

    // 设置单位
    if (type == TYPE_YCDISPLY_PRIMARY) // 一次值
    {
        Telemet_opt[46].Company = Non_Numeric[OPT_UINT].opt[2]; // KW
        Telemet_opt[47].Company = Non_Numeric[OPT_UINT].opt[4];
        Telemet_opt[48].Company = Non_Numeric[OPT_UINT].opt[6];
    }
    if (type == TYPE_YCDISPLY_SECONDY) // 二次值
    {
        Telemet_opt[46].Company = Non_Numeric[OPT_UINT].opt[3];
        Telemet_opt[47].Company = Non_Numeric[OPT_UINT].opt[5];
        Telemet_opt[48].Company = Non_Numeric[OPT_UINT].opt[7];
    }
}

/**
 * @brief           初始化实时数据模块
 * @return         * void 
 * @retval         
 * 
 * @warning        
 * @note           
 */
void data_real_time_init(void)
{
    data_real_time_get_yx_data();
    
    data_real_time_get_yc_data(TYPE_YCDISPLY_PRIMARY);
    
    data_real_time_get_yk_data();
}

/**
 * @brief           获取遥信总数量
 * @return         * uint8_t 遥信总数量
 * @retval         
 * 
 * @warning        
 * @note           返回当前配置的遥信总数量，该值在data_real_time_get_yx_data()中更新
 */
uint8_t data_real_time_get_yx_count(void)
{
    // printf("%s g_yx_total_count = %d\n", __FUNCTION__, g_yx_total_count);
    return g_yx_total_count;
}

/**
 * @brief           获取并更新遥控数据
 * @return         * void 
 * @retval         
 * 
 * @warning        
 * @note           参考原有GetandChange_disp_yk函数实现
 */
void data_real_time_get_yk_data(void)
{
    static struct equ_config_do *ecdo;
    u8 num = 0;
    int g_sw = 0;
    u8 stu_f = 0;

    g_sw = g_equ_config->do_num;
    if (g_sw > SUBMENU_REMOTCRTL_NUM)
        g_sw = SUBMENU_REMOTCRTL_NUM;

    for (num = 0; num < g_sw; num++)
    {
        if ((short)g_equ_config_do[num].type != INDEX_INVALLID)
        {
            ecdo = &g_equ_config_do[num];
            // 填充选项名称
            Remote_ctrl_opt[num].opt = &ecdo->name[0];

            // 获取DO对应DI的状态，通过DI统一获取应急系统使能状态
            // DO和DI统一获取应急系统使能状态
            stu_f = dido_di_is_on(ecdo->slot, ecdo->index);
            Remote_ctrl_opt[num].value = stu_f;

            // 填充状态显示内容
            if (stu_f < 2)
            {
                Remote_ctrl_opt[num].Company = Non_Numeric[OPT_YXSTA].opt[stu_f];
            }
            else
            {
                Remote_ctrl_opt[num].Company = "";
            }
        }
        else
        {
            Remote_ctrl_opt[num].opt = Non_Numeric[OPT_YXSTA].opt[2];
            Remote_ctrl_opt[num].Company = "";
            Remote_ctrl_opt[num].value = 2; // 未知状态
        }
    }
}
