#include "lc_system.h"
#include "pub_fun.h"
#include "define.h"
#include "../cmdclient.h"
#include "../multilanguage.h"
#include "collector-api.h"
#include <math.h>
SYSTEM_INFO system_info;

extern int g_proto_log_level;
extern int g_ems_log_level;

#define EMS_LOG_LEVEL "EMS_Loglv"
#define PRO_LOG_LEVEL "ProtoLoglv"
static int write_log_level_cb(char *name, void *value_v)
{
    int *value = value_v;
    ems_syslog(LOG_NOTICE, "write name:%s,value:%d", name, *value);
    if (*value > 7)
        *value = 7;
    if (*value < 1)
        *value = 1;
    if (strcmp(EMS_LOG_LEVEL, name) == 0)
    {
        g_ems_log_level = *value;
    }
    else if (strcmp(PRO_LOG_LEVEL, name) == 0)
    {
        g_proto_log_level = *value;
    }
    return 0;
}

static int read_log_level_cb(char *name, void *value_v)
{
    int *value = value_v;
    if (strcmp(EMS_LOG_LEVEL, name) == 0)
    {
        *value = g_ems_log_level;
    }
    else if (strcmp(PRO_LOG_LEVEL, name) == 0)
    {
        *value = g_proto_log_level;
    }
    // ems_syslog(LOG_NOTICE,"read name:%s,value:%d",name,*value);
    return 0;
}

static char *read_device_cfg(void)
{
    return read_file_data(CONFIG_PATH "/lc/" COLLECTOR_DEVICE);
}

static char *read_port_cfg(void)
{
    return read_file_data(DEV_PORT_CFG_FILE);
}

static char *read_lc_cfg(void)
{
    return read_file_data(LC_CFG_FILE);
}

static char *read_automatic_cfg(void)
{
    return read_file_data(LC_AUTOMATIC_CONFIG);
}

static const char *config_list[] =
    {
        CONFIG_PATH "/lc/" COLLECTOR_DEVICE,
        DEV_PORT_CFG_FILE,
        LC_CFG_FILE,
        LC_AUTOMATIC_CONFIG,
};

static char *read_export_config(void)
{
    char *pp = NULL;
    cJSON *root = cJSON_CreateArray();
    if (root == NULL)
    {
        free(root);
        return NULL;
    }
    //
    cJSON *cfg = NULL;
    for (int i = 0; i < sizeof(config_list) / sizeof(config_list[0]); i++)
    {
        cfg = cJSON_CreateObject();
        if (cfg != NULL)
        {
            cJSON_AddItemToObject(cfg, "path", cJSON_CreateString(config_list[i]));
            pp = read_file_data(config_list[i]);
            if (pp != NULL)
            {
                cJSON_AddItemToObject(cfg, "err", cJSON_CreateNumber(0));
                cJSON_AddItemToObject(cfg, "data", cJSON_CreateString(pp));
                free(pp);
            }
            else
            {
                cJSON_AddItemToObject(cfg, "err", cJSON_CreateNumber(1));
            }
            cJSON_AddItemToArray(root, cfg);
        }
    }
    char *ret = cJSON_Print(root);

    cJSON_Delete(root);
    return ret;
}

static char *read_lang_config(void)
{
    return read_file_data(ENV_LANG_CFG_FILE);
}

static char *read_dev_info(void)
{
    const char *dev_info = get_proto_forward_var()->dev_info_string;
    return strdup(dev_info);
}

int ua_read_cfg_cb(function_data *input, int input_num, function_data *output, int *output_num)
{
    const static struct cmd_map
    {
        const char *cmd;
        char *(*get_result)(void);
    } cmd_map[] =
        {
            {.cmd = DEVICE_CONFIG_NAME, .get_result = read_device_cfg},
            {.cmd = PORT_CONFIG_NAME, .get_result = read_port_cfg},
            {.cmd = LC_CFG_NAME, .get_result = read_lc_cfg},
            {.cmd = LC_AUTOMATIC_NAME, .get_result = read_automatic_cfg},
            {.cmd = "export_config", .get_result = read_export_config},
            {.cmd = ENV_LANG, .get_result = read_lang_config},
            {.cmd = DEV_INFO_CONFIG_NAME, .get_result = read_dev_info},
        };
    //
    char *cmd = (input != NULL) ? input[0].data : NULL;
    if ((input_num == 0) || (cmd == NULL))
    {
        goto read_cfg_notice;
    }
    int cmd_len = input[0].data_len;
    //
    char *(*get_result)(void) = NULL;
    for (int i = 0; i < sizeof(cmd_map) / sizeof(cmd_map[0]); i++)
    {
        if ((strlen(cmd_map[i].cmd) == cmd_len) && (memcmp(cmd, cmd_map[i].cmd, cmd_len) == 0))
        {
            get_result = cmd_map[i].get_result;
            break;
        }
    }
    //
    if (get_result != NULL)
    {
        cmd = get_result();
        if (cmd == NULL)
        {
            cmd = strdup("{\"result\":\"error\", \"info\":\"read file error\"}");
        }

        output[0].data = cmd;
        output[0].data_len = strlen(cmd);
        *output_num = 1;
        return 0;
    }
    //
    cJSON *root = NULL;
    cJSON *arr = NULL;
read_cfg_notice:
    root = cJSON_CreateObject();
    arr = cJSON_CreateArray();
    cJSON_AddItemToObject(root, "result", cJSON_CreateString("error"));
    for (int i = 0; i < sizeof(cmd_map) / sizeof(cmd_map[0]); i++)
    {
        cJSON_AddItemToArray(arr, cJSON_CreateString(cmd_map[i].cmd));
    }
    cJSON_AddItemToObject(root, "parameter list", arr);
    //
    output[0].data = cJSON_PrintUnformatted(root);
    output[0].data_len = strlen(output[0].data);
    *output_num = 1;
    //
    cJSON_Delete(root);
    return 0;
}

static int write_device_cfg(char *p, int len)
{
    if (p == NULL)
    {
        return -123;
    }
    return write_file_data(CONFIG_PATH "/lc/" COLLECTOR_DEVICE, p, len);
}

static int write_port_cfg(char *p, int len)
{
    if (p == NULL)
    {
        return -123;
    }
    cJSON* root = json_parse_string_with_comments(p);
    set_dido_common_config(root);
    return write_file_data(DEV_PORT_CFG_FILE, p, len);
}

static int write_lc_cfg(char *p, int len)
{
    if (p == NULL)
    {
        return -123;
    }
    return write_file_data(LC_CFG_FILE, p, len);
}

static int write_automatic_cfg(char *p, int len)
{
    if (p == NULL)
    {
        return -123;
    }
    return write_file_data(LC_AUTOMATIC_CONFIG, p, len);
}



static int write_import_config(char *data, int len)
{
    int ret = 0;
    cJSON *cfg = NULL;
    cJSON *path = NULL;
    cJSON *tmp = NULL;
    cJSON *json = cJSON_ParseWithLength(data, len);
    if (json == NULL)
    {
        return -1;
    }

    int cfg_sum = cJSON_GetArraySize(json);
    for (int i = 0; i < cfg_sum; i++)
    {
        cfg = cJSON_GetArrayItem(json, i);
        path = cJSON_GetObjectItemCaseSensitive(cfg, "path");
        tmp = cJSON_GetObjectItemCaseSensitive(cfg, "err");
        if ((tmp == NULL) || (tmp->valueint != 0))
        {
            ret = -2;
            ems_syslog(LOG_ERR, "path:%s, err:%d", (path->valuestring == NULL) ? "NULL" : path->valuestring, tmp->valueint);
            continue;
        }
        tmp = cJSON_GetObjectItemCaseSensitive(cfg, "data");
        ems_syslog(LOG_NOTICE, "%s->%s", path->valuestring, tmp->valuestring);
        if (0 != write_file_data(path->valuestring, tmp->valuestring, strlen(tmp->valuestring)))
        {
            ems_syslog(LOG_ERR, "write  import lc cfg error:%s", path->valuestring);
            ret = -3;
        }
        else
        {
            ems_syslog(LOG_NOTICE, "write import lc cfg ok, save to %s", path->valuestring);
        }
    }
    cJSON_Delete(json);
    return ret;
}

static int write_lang_config(char *p, int len)
{
    if (p == NULL)
    {
        return -123;
    }
    int ret = write_file_data(ENV_LANG_CFG_FILE, p, len);
    get_pcs_ctrl_var()->reboot_flag = 1;
    return ret;
}


int ua_write_cfg_cb(function_data *input, int input_num, function_data *output, int *output_num)
{
    const static struct cmd_map
    {
        const char *cmd;
        int (*hand)(char *par, int len);
        int not_json;
    } cmd_map[] =
        {
            {.cmd = DEVICE_CONFIG_NAME, .hand = write_device_cfg},
            {.cmd = PORT_CONFIG_NAME, .hand = write_port_cfg},
            {.cmd = LC_CFG_NAME, .hand = write_lc_cfg},
            {.cmd = LC_AUTOMATIC_NAME, .hand = write_automatic_cfg},
            {.cmd = "import_config", .hand = write_import_config},
            {.cmd = ENV_LANG, .hand = write_lang_config, .not_json = 1},
        };
    //
    char *cmd = (input != NULL) ? input[0].data : NULL;
    char *content = (input != NULL) ? input[1].data : NULL;
    if ((input_num == 0) || (cmd == NULL) || (content == NULL))
    {
        goto write_cfg_notice;
    }
    int cmd_len = input[0].data_len;
    int content_len = input[1].data_len;
    //
    int (*hand)(char *par, int len) = NULL;
    int not_json = 0;
    for (int i = 0; i < sizeof(cmd_map) / sizeof(cmd_map[0]); i++)
    {
        if ((strlen(cmd_map[i].cmd) == cmd_len) && memcmp(cmd, cmd_map[i].cmd, cmd_len) == 0)
        {
            hand = cmd_map[i].hand;
            not_json = cmd_map[i].not_json;
            break;
        }
    }
    //
    cmd = NULL;
    if (hand != NULL)
    {
        if (not_json == 0) // 是json格式
        {
            cJSON *obj = cJSON_ParseWithLength(content, content_len);
            if (obj == NULL)
            {
                cmd = strdup("{\"result\":\"error\", \"info\":\"write content must be json format\"}");
            }
            else
            {
                cJSON_Delete(obj);
            }
        }

        if (cmd == NULL)
        {
            if (hand(content, content_len) == 0)
            {
                cmd = strdup("{\"result\":\"ok\"}");
            }
            else
            {
                cmd = strdup("{\"result\":\"error\", \"info\":\"write error\"}");
            }
        }
        output[0].data = cmd;
        output[0].data_len = strlen(cmd);
        *output_num = 1;
        return 0;
    }
    //
    cJSON *root = NULL;
    cJSON *arr = NULL;
write_cfg_notice:
    root = cJSON_CreateObject();
    arr = cJSON_CreateArray();
    cJSON_AddItemToObject(root, "result", cJSON_CreateString("error"));
    for (int i = 0; i < sizeof(cmd_map) / sizeof(cmd_map[0]); i++)
    {
        cJSON_AddItemToArray(arr, cJSON_CreateString(cmd_map[i].cmd));
    }
    cJSON_AddItemToObject(root, "parameter list", arr);
    //
    output[0].data = cJSON_PrintUnformatted(root);
    output[0].data_len = strlen(output[0].data);
    *output_num = 1;
    //
    cJSON_Delete(root);
    return 0;
}

int ua_get_alarm_cb(function_data *input, int input_num, function_data *output, int *output_num)
{
    char all_info[1024 * 8] = {0};

    sprintf(all_info, "{\"result\":\"error\"}");
    output[0].data = strdup(all_info);
    output[0].data_len = strlen(all_info);
    *output_num = 1;

    return 0;
}

int ua_lcAgentSet(function_data *input, int input_num, function_data *output, int *output_num)
{
    int ret;
    const char * fmtstr;
    char gwsn[32], tmpbuf[256], * reply;
    char *sn = NULL, *cmd = NULL, *ipaddr = NULL;
    static time_t last_upgrade_sync;

    ret = 0;
    reply = NULL;
    if (input == NULL || input_num < 3) {
        ems_syslog(LOG_ERR, "Invalid number of input: %d", input_num);
        goto error;
    }

    sn = input[0].data;
    cmd = input[1].data;
    ipaddr = input[2].data;
    if (sn == NULL || cmd == NULL || ipaddr == NULL) {
        ems_syslog(LOG_ERR, "Invalid NULL argument for %s", __FUNCTION__);
        goto error;
    }
    sn = calloc(1, input[0].data_len + 10);
    memcpy(sn, input[0].data, input[0].data_len);
    //
    cmd = calloc(1, input[1].data_len + 10);
    memcpy(cmd, input[1].data, input[1].data_len);
    //
    ipaddr = calloc(1, input[2].data_len + 10);
    memcpy(ipaddr, input[2].data, input[2].data_len);

    memset(gwsn, 0, sizeof(gwsn));
    get_board_sn(gwsn);
    if (strcmp(gwsn, sn) != 0) {
        ems_syslog(LOG_ERR, "Error, invalid LC device sn: %s, expected: %s", sn, gwsn);
        goto error;
    }

    fmtstr = "/opt/lnxall_app/bin/lcAgentSet_%s %s";
    ems_syslog(LOG_ERR, "Processing command '%s' from %s", cmd, ipaddr);
    if (strcmp(cmd, LC_AGENT_RESTART) == 0) {
        snprintf(tmpbuf, sizeof(tmpbuf), fmtstr, "restart", ipaddr);
        ret = cmd_call(tmpbuf, 5, NULL, 0);
    } else if (strcmp(cmd, LC_AGENT_REBOOT) == 0) {
        snprintf(tmpbuf, sizeof(tmpbuf), fmtstr, "reboot", ipaddr);
        ret = cmd_call(tmpbuf, 5, NULL, 0);
    } else if (strcmp(cmd, LC_AGENT_UPGRADE) == 0) {
        time_t now = time(NULL);
        if (now >= last_upgrade_sync && (now - last_upgrade_sync) < 10) {
            ret = -1;
            reply = strdup("Last upgrade/templatesync might be in progress");
            ems_syslog(LOG_ERR, "No LC upgrade in 10 seconds");
        } else {
            last_upgrade_sync = now;
            snprintf(tmpbuf, sizeof(tmpbuf), fmtstr, "upgrade", ipaddr);
            ret = cmd_call(tmpbuf, 5, NULL, 0);
        }
    } else if (strcmp(cmd, LC_AGENT_UPGRADEN) == 0) {
        time_t now = time(NULL);
        if (now >= last_upgrade_sync && (now - last_upgrade_sync) < 10) {
            ret = -1;
            reply = strdup("Last upgrade/templatesync might be in progress");
            ems_syslog(LOG_ERR, "No LC upgrade in 10 seconds");
        } else {
            char bufn[40];
            last_upgrade_sync = now;
            snprintf(bufn, sizeof(bufn), "%s -n", ipaddr);
            snprintf(tmpbuf, sizeof(tmpbuf), fmtstr, "upgrade", bufn);
            ret = cmd_call(tmpbuf, 5, NULL, 0);
        }
    } else if (strcmp(cmd, LC_AGENT_TEMPLATESYNC) == 0) {
        time_t now = time(NULL);
        if (now >= last_upgrade_sync && (now - last_upgrade_sync) < 10) {
            ret = -1;
            reply = strdup("Last upgrade/templatesync might be in progress");
            ems_syslog(LOG_ERR, "No LC template sync in 10 seconds");
        } else {
            last_upgrade_sync = now;
            snprintf(tmpbuf, sizeof(tmpbuf), fmtstr, "templatesync", ipaddr);
            ret = cmd_call(tmpbuf, 6, &reply, 1);
        }
    } else {
        ret = -1;
        reply = strdup("Unsupported lcAgentSet command, command:" LC_AGENT_RESTART "," LC_AGENT_REBOOT "," LC_AGENT_UPGRADE "," LC_AGENT_UPGRADEN "," LC_AGENT_TEMPLATESYNC);
    }

    *output_num = 1;
    if (reply != NULL) {
        snprintf(tmpbuf, sizeof(tmpbuf), "{\"result\":\"%s\",\"reply\":\"%s\"}",
            ret == 0 ? "ok" : "error", reply);
    } else {
        snprintf(tmpbuf, sizeof(tmpbuf), "{\"result\":\"%s\"}",
            ret == 0 ? "ok" : "error");
    }
    output[0].data = strdup(tmpbuf);
    output[0].data_len = strlen(output[0].data);
    free(reply);
    return 0;

error:
    if (sn != NULL)
    {
        free(sn);
    }
    if (cmd != NULL)
    {
        free(cmd);
    }
    if (ipaddr == NULL)
    {
        free(ipaddr);
    }
    *output_num = 1;
    output[0].data = strdup("{\"result\":\"error\"}");
    output[0].data_len = strlen(output[0].data);
    if (reply != NULL)
        free(reply);
    return 0;
}

/**
 * @description: 调用设置接口-下层对应用层提供的接口（调用适配器或点位映射）
 * @param {function_data} *input
 * @param {int} input_num
 * @param {function_data} *output
 * @param {int} *output_num
 * @return {*}
 */
int ua_set_function(function_data *input, int input_num, function_data *output, int *output_num)
{
    if (input_num < 3 || input[0].data_len > TAG_NAME_LEN || input[1].data_len > TAG_NAME_LEN || input[2].data_len > TAG_NAME_LEN)
    {
        output[0].data     = strdup(_("Please enter the correct page number and page size."));
        output[0].data_len = strlen(output[0].data);
        *output_num = 1;
        return -1;
    }
    int ret = 0;
    char str[3][TAG_NAME_LEN + 2] = {"", "", ""};
    memcpy(str[0], input[0].data, input[0].data_len);
    memcpy(str[1], input[1].data, input[1].data_len);
    memcpy(str[2], input[2].data, input[2].data_len);
    
    char *endptr;
    double value;
    char *return_str = "";

    // 将字符串转换为 double
    value = strtod(str[2], &endptr);

    // 检查转换是否成功
    if (str[2] == endptr) {
        return_str = "Error: Invalid set value!";
        goto END;
    } else if (errno == ERANGE) {
        if (value == HUGE_VAL) {
            return_str = "Error: Exceed conversion limit!";
            goto END;

        } else if (value == -HUGE_VAL) {
            return_str = "Error: Out of conversion limit!";
            goto END;
        }
    }

    
    ret = dev_set_function(str[0], str[1], value);

    if(-1 == ret)
    {
        return_str = "pe get obj failed";
        goto END;
        
    }

    if(-2 == ret)
    {
        return_str = "set value failed";
        goto END;
    }

    if(0 == ret)
    {
        return_str = "set value success";
        goto END;
    }

END:
    output[0].data     = strdup(return_str);
    output[0].data_len = strlen(output[0].data);
    *output_num = 1;
    return 0;
}

/**
 * @description: 调用数据获取接口-下层对应用层提供的接口（调用适配器或点位映射）
 * @param {function_data} *input
 * @param {int} input_num
 * @param {function_data} *output
 * @param {int} *output_num
 * @return {*}
 */
int ua_get_function(function_data *input, int input_num, function_data *output, int *output_num)
{
    if (input_num < 2)
    {
        output[0].data     = strdup(_("Please enter the correct page number and page size."));
        output[0].data_len = strlen(output[0].data);
        *output_num = 1;
        return -1;
    }
    double value = 0;
    int ret = 0;
    
    ret = dev_get_function_double(input[0].data, input[1].data, &value);

    if(-1 == ret)
    {
        output[0].data     = strdup("pe get obj failed");
        output[0].data_len = strlen(output[0].data);
        *output_num = 1;
        return -1;
    }

    if(-2 == ret)
    {
        output[0].data     = strdup("get value failed");
        output[0].data_len = strlen(output[0].data);
        *output_num = 1;
        return -1;
    }


    char str_tmp[50] = "";
    sprintf(str_tmp, "%lf", value);
    output[0].data     = strdup(str_tmp);
    output[0].data_len = strlen(output[0].data);
    *output_num = 1;
    return 0;
}


int add_lc_system_info(UA_SERVER_PARAM *ua_param)
{
    ua_add_file(ua_param->ua_server, UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER), &system_info.systemNodeId, "System", "System");
    {
        char tmp_ch[128] = {0};
        ua_add_file(ua_param->ua_server, system_info.systemNodeId, &system_info.aboutInfo.aboutNodeId, "About", _("About"));
        {
            total_cb_t *total_cb_s = calloc(sizeof(total_cb_t), 1);
            total_cb_s->onRead = read_sim_cb;
            total_cb_s->onWrite = NULL;
            creat_a_rw_string(ua_param, _("SIM card number"), "SIM_No", &system_info.aboutInfo.iccidNodeId, system_info.aboutInfo.aboutNodeId, _("Acquisition failed"), total_cb_s);

            sprintf(tmp_ch, "%s", SW_VERSION);
            creat_a_base_string(ua_param, "EmsVer", _("EMS version"), &system_info.aboutInfo.versionNodeId, system_info.aboutInfo.aboutNodeId, tmp_ch);
            
            char gw_sn[SN_MAX_LEN] = {0};
            if (0 == get_board_sn(gw_sn))
            {
                sprintf(tmp_ch,"%s", gw_sn);
            }
            else
            {
                sprintf(tmp_ch,"unknown");
            }
            creat_a_base_string(ua_param, "DevNo", _("Controller number"), &system_info.aboutInfo.cabNumNodeId, system_info.aboutInfo.aboutNodeId, tmp_ch);

            if (get_product_name(gw_sn) == 0)
            {
                sprintf(tmp_ch, "%s", gw_sn);
            }
            else
            {
                sprintf(tmp_ch, "unknown");
            }
            creat_a_base_string(ua_param, "EmsProduct", _("Ems Product"), &system_info.aboutInfo.productNodeId, system_info.aboutInfo.aboutNodeId, tmp_ch);

        }
    }

    ua_add_file(ua_param->ua_server, system_info.systemNodeId, &system_info.stateInfo.stateNodeId, "Status", _("Status"));
    {
        creat_a_base_double(ua_param, "CPU", _("CPU"), &system_info.stateInfo.CPUNodeId, system_info.stateInfo.stateNodeId, _("Not obtained"));
        creat_a_base_string(ua_param, "Memroy", _("Memory"), &system_info.stateInfo.memNodeId, system_info.stateInfo.stateNodeId, _("Not obtained"));
        creat_a_base_string(ua_param, "Flash", _("Hard disk(used/total MB)"), &system_info.stateInfo.diskNodeId, system_info.stateInfo.stateNodeId, _("Not obtained"));
        pthread_t get_cycle_info_tid = PTHREAD_NULL;
        if (0 == pthread_create(&get_cycle_info_tid, NULL, get_cycle_info, ua_param))
        {
            pthread_setname_np(get_cycle_info_tid, "get cycle info");
        }
        //
        total_cb_t *totle_cb = calloc(sizeof(total_cb_t), 1);
        totle_cb->onRead = read_ems_connect_cb;
        totle_cb->onWrite = NULL;
        if (0 != add_int_to_node(ua_param->ua_server, system_info.stateInfo.stateNodeId, true, &system_info.stateInfo.EsmConnectNodeId,
                        EMS_CONNECT_STATE, _("EMS connection status"), totle_cb))
        {
            free(totle_cb);
        }

        totle_cb = calloc(sizeof(total_cb_t), 1);
        totle_cb->onRead = read_ems_heartbeat_cb;
        totle_cb->onWrite = write_ems_heartbeat_cb;
        if (0 != add_int_to_node(ua_param->ua_server, system_info.stateInfo.stateNodeId, false, &system_info.stateInfo.EmsHeartbeatNodeId,
                        EMS_HEARTBEAT, _("EMS heartbeat"), totle_cb))
        {
            free(totle_cb);
        }
    }

    ua_add_file(ua_param->ua_server, system_info.systemNodeId, &system_info.debugInfo.debugNodeId, "Debug", _("Debugging"));
    {
        total_cb_t *totle_cb = calloc(sizeof(total_cb_t), 1);
        totle_cb->onRead = read_log_level_cb;
        totle_cb->onWrite = write_log_level_cb;

        if (0 != add_int_to_node(ua_param->ua_server, system_info.debugInfo.debugNodeId, false, &system_info.debugInfo.emsLogLevelNodeId,
                                 EMS_LOG_LEVEL, _("EMS log level"), totle_cb))
        {
            free(totle_cb);
        }
        if (0 != add_int_to_node(ua_param->ua_server, system_info.debugInfo.debugNodeId, false, &system_info.debugInfo.protoLogLevelNodeId,
                                 PRO_LOG_LEVEL, _("Data acquisition log level"), totle_cb))
        {
            free(totle_cb);
        }
    }

    ua_add_file(ua_param->ua_server, system_info.systemNodeId, &system_info.expertInfo.expertNodeId, "Advance", _("Advanced features"));
    {
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 1, (char*[]){"name"}, 1, (char*[]){"result"}, "ReadCfg", _("Read configuration"), ua_read_cfg_cb);
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 2, (char*[]){"name", "content"}, 1, (char*[]){"result"}, "WriteCfg", _("Write configuration"), ua_write_cfg_cb);
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 0, (char*[]){NULL}, 1, (char*[]){"result"}, "getAlarmInfo", _("Obtain alarm information"), ua_get_alarm_cb);
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 3, (char*[]){"sn", "command", "emsipaddr"}, 1, (char*[]){"result"}, "lcAgentSet", _("Proxy LC control"), ua_lcAgentSet);
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 3, (char*[]){"dev_no", "function", "set_value"}, 1, (char*[]){"result"}, "ua_set_function", _("Write operation interface"), ua_set_function);
        addMethodToNode(ua_param, system_info.expertInfo.expertNodeId, 2, (char*[]){"dev_no", "function"}, 1, (char*[]){"result"}, "ua_get_function", _("Read operation interface"), ua_get_function);

    }

    return 0;
}

void check_lc_update_aircond_startstop(float power)
{
   int tval = dev_get_dev_tag_int(DEV_NO_LC, AIR_COND_STARTSTOP_CTRL);
    ac_set_mode_api(tval);     // 1:开机; 0:停机  
}
