#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "cJSON.h"

#include "my_public.h"
#include "pcs_dev.h"

#define PCS_DEV_FILE "/app/config/ems/pcs_dev.json"


#define SERVICEUPCONT var->devNodeInfo.serviceupcont
#define SERVICEDOWNCONT var->devNodeInfo.servicedowncont
#define SERVICE_DOWN var->devNodeInfo.pserviceInfoDOWN
#define SERVICE_UP var->devNodeInfo.pserviceInfoUP

#define POWER_UNIT_VAL 10

PCS_TYPE_OPERATE_T pcs_type_operate[] = {{1, 1, 1}, {0xff00, 0, 1}};

static void pcs_power3x_set_to_dev(pcs_dev_var_t *var, int index)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *sub = NULL;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};
    for (i = 0; i < var->devNodeInfo.servicetodevcont; i++)
    {
        if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].name, "3xyggl") == 0)
        {
            dbg_syslog(LOG_DEBUG, "yggl set id:%s", var->devNodeInfo.pserviceInfoTodev[i].identifier);
            if (index < var->devNodeInfo.devcont)
            {
                num = var->devNodeInfo.pserviceInfoTodev[i].tagNode.nodecont;
                for (n = 0; n < num; n++)
                {
                    tag_data = cJSON_CreateObject();
                    // cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
                    cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[index].devSn);
                    cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                    cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                    cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                    dbg_syslog(LOG_DEBUG, "name:%s", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                    cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].tag, var->devNodeInfo.pdevnodecfg[index].pcsInfo.yggl / num);
                    data_tmp = cJSON_Print(tag_data);
                    publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                    free(data_tmp);
                    cJSON_Delete(tag_data);
                }
            }
        }
    }
}

static void pcs_power_set_to_dev(pcs_dev_var_t *var, int index)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *sub = NULL;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};

    for (i = 0; i < var->devNodeInfo.servicetodevcont; i++)
    {
        if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].name, "yggl") == 0)
        {
            dbg_syslog(LOG_DEBUG, "yggl set id:%s", var->devNodeInfo.pserviceInfoTodev[i].identifier);
            for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[i].tagNode.nodecont; n++)
            {
                dbg_syslog(LOG_DEBUG, "name:%s", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name, "yggl") == 0)
                {

                    // for (j = 0; j < var->devNodeInfo.devcont; j++)
                    if (index < var->devNodeInfo.devcont)
                    {
                        tag_data = cJSON_CreateObject();
                        // cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[index].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[i].identifier);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].tag, var->devNodeInfo.pdevnodecfg[index].pcsInfo.yggl);
                        data_tmp = cJSON_Print(tag_data);
                        if (var->devNodeInfo.pdevnodecfg[index].pcsInfo.yggl == 0)
                        {
                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                        }
                        else
                        {
                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                        }
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
    }
}

static void pcs_power_set_in(pcs_dev_var_t *var, int i)
{
    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl > 0)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl > var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxChargeP * POWER_UNIT_VAL)
        {

            var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxChargeP * POWER_UNIT_VAL;
        }
    }
    else if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl < 0)
    {

        if (-var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl > var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxDischarP * POWER_UNIT_VAL)
        {

            var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = -var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxDischarP * POWER_UNIT_VAL;
        }
    }
    dbg_syslog(LOG_DEBUG, "i:%d set power:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl);
    if (var->pcsType == 0)
    {
        pcs_power_set_to_dev(var, i); // 变更设置
    }
    else
    {
        // 三相功率
        pcs_power3x_set_to_dev(var, i);
    }
}

static void pcs_power_set(double power, pcs_dev_var_t *var)
{
    int i, j, num = 0;
    // todo 判断设备正常情况。
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            num++;
        }
    }
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            dbg_syslog(LOG_DEBUG, "index: %d ->yggl: %d power:%f", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl, power * POWER_UNIT_VAL / num);
            if (var->pcsType == 0)
            {
                if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl != power * POWER_UNIT_VAL / num)
                {
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = power * POWER_UNIT_VAL / num;
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont = 0;
                    pcs_power_set_in(var, i);

                }
                else
                {
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont++;
                    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont >= PCS_POWER_EQ_SET_NUM)
                    {
                        pcs_power_set_in(var, i);
                        var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont = 0;
                    }
                }
            }
            else
            {
                if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl != power * POWER_UNIT_VAL / num)
                {
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = power * POWER_UNIT_VAL / num;
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont = 0;
                    pcs_power_set_in(var, i);
                }
                else
                {
                    var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont++;
                    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont >= PCS_POWER_EQ_SET_NUM)
                    {
                        pcs_power_set_in(var, i);
                        var->devNodeInfo.pdevnodecfg[i].pcsInfo.cont = 0;
                    }
                }
            }

            dbg_syslog(LOG_DEBUG, "i:%d power:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl);
        }
        else
        {
            if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl != 0)
            {
                var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = 0;
                dbg_syslog(LOG_DEBUG, "err i:%d set power:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl);
                if (var->pcsType == 0)
                {
                    pcs_power_set_to_dev(var, i);
                }
                else
                {
                    // 三相功率
                    pcs_power3x_set_to_dev(var, i);
                }
            }
        }
    }
    //    pcs_power_set_to_dev(var);//每次设置
}

static void pcs_wggl3x_set_to_dev(pcs_dev_var_t *var, int index)
{
    {
        int i, j, n;
        CHAR *data_tmp = NULL;
        int err = 1, num = 0;
        cJSON *sub = NULL;
        cJSON *tag_data;
        CHAR tagNode[64] = {0};
        for (i = 0; i < var->devNodeInfo.servicetodevcont; i++)
        {
            if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].name, "3xwggl") == 0)
            {
                dbg_syslog(LOG_DEBUG, "wggl set id:%s", var->devNodeInfo.pserviceInfoTodev[i].identifier);
                if (index < var->devNodeInfo.devcont)
                {

                    num = var->devNodeInfo.pserviceInfoTodev[i].tagNode.nodecont;
                    for (n = 0; n < num; n++)
                    {
                        tag_data = cJSON_CreateObject();
                        // cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[index].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                        dbg_syslog(LOG_DEBUG, "name:%s", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].tag, var->devNodeInfo.pdevnodecfg[index].pcsInfo.wggl / num);
                        data_tmp = cJSON_Print(tag_data);
                        publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
    }
}

static void pcs_wggl_set_to_dev(pcs_dev_var_t *var, int index)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *sub = NULL;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};

    for (i = 0; i < var->devNodeInfo.servicetodevcont; i++)
    {
        if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].name, "yggl") == 0)
        {
            dbg_syslog(LOG_DEBUG, "yggl set id:%s", var->devNodeInfo.pserviceInfoTodev[i].identifier);
            for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[i].tagNode.nodecont; n++)
            {
                dbg_syslog(LOG_DEBUG, "name:%s", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name);
                if (strcmp(var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].name, "yggl") == 0)
                {
                    if (index < var->devNodeInfo.devcont)
                    {
                        tag_data = cJSON_CreateObject();
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[index].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[i].identifier);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[n].tag, var->devNodeInfo.pdevnodecfg[index].pcsInfo.yggl);
                        data_tmp = cJSON_Print(tag_data);
                        if (var->devNodeInfo.pdevnodecfg[index].pcsInfo.yggl == 0)
                        {
                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                        }
                        else
                        {
                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[index].devSn, var->devNodeInfo.pdevnodecfg[index].type);
                        }
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
    }
}

static void pcs_wggl_set(WORD power, pcs_dev_var_t *var)
{
    int i, j, num = 0;
    // todo 判断设备正常情况。
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            num++;
        }
    }
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            dbg_syslog(LOG_DEBUG, "index: %d ->wggl: %d power:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl, power * POWER_UNIT_VAL / num);
            if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl != power * POWER_UNIT_VAL / num)
            {
                var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl = power * POWER_UNIT_VAL / num;
                if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl > 0)
                {
                    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl > var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxChargeP * POWER_UNIT_VAL)
                    {

                        var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl = var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxChargeP * POWER_UNIT_VAL;
                    }
                }
                else if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl < 0)
                {

                    if (-var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl > var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxDischarP * POWER_UNIT_VAL)
                    {

                        var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl = -var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxDischarP * POWER_UNIT_VAL;
                    }
                }
                dbg_syslog(LOG_DEBUG, "i:%d set wggl:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl);
                if (var->pcsType == 0)
                {
                    pcs_wggl_set_to_dev(var, i); // 变更设置
                }
                else
                {
                    pcs_wggl3x_set_to_dev(var, i);
                }
            }
            dbg_syslog(LOG_DEBUG, "i:%d wggl:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl);
        }
        else
        {
            if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl != 0)
            {
                var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl = 0;
                dbg_syslog(LOG_DEBUG, "i:%d set wggl:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.wggl);
                if (var->pcsType == 0)
                {
                    pcs_wggl_set_to_dev(var, i);
                }
                else
                {
                    pcs_wggl3x_set_to_dev(var, i);
                }
            }
        }
    }
}

static void pcs_connect_set(pcs_dev_var_t *var)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        // if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0 && var->devNodeInfo.pdevnodecfg[i].pcsInfo.conenable == 1)
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.connect = 1;
            // todo 设置联网
            for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
            {
                if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, "connect") == 0)
                {
                    dbg_syslog(LOG_DEBUG, "connect set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                    for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                    {
                        if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, "connect") == 0)
                        {

                            tag_data = cJSON_CreateObject();
                            // cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
                            cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                            cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                            cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                            cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                            cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].open);
                            data_tmp = cJSON_Print(tag_data);
                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);
                            free(data_tmp);
                            cJSON_Delete(tag_data);
                        }
                    }
                }
            }
            dbg_syslog(LOG_DEBUG, "num:%d connect", i);
        }
        else
        {
            dbg_syslog(LOG_DEBUG, "num:%d conenable disable errState:%d conenable:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState, var->devNodeInfo.pdevnodecfg[i].pcsInfo.conenable);
        }
    }
}

static void pcs_disconnect_set(pcs_dev_var_t *var)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.connect == 1)
        {
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.connect = 0;
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.yggl = 0; // 功率清零
            // todo 设置离网
            for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
            {
                if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, "disconnect") == 0)
                {
                    dbg_syslog(LOG_DEBUG, "disconnect set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                    for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                    {
                        if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, "disconnect") == 0)
                        {

                            tag_data = cJSON_CreateObject();
                            // cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
                            cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                            cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                            cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                            cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                            dbg_syslog(LOG_DEBUG, "send publish identifier:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                            cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].close);
                            data_tmp = cJSON_Print(tag_data);

                            publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);

                            free(data_tmp);
                            cJSON_Delete(tag_data);
                        }
                    }
                }
            }
            dbg_syslog(LOG_DEBUG, "num:%d disconnect", i);
        }
        else
        {
            dbg_syslog(LOG_DEBUG, "num:%d connect is disconnect connect:%d", i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.connect);
        }
    }
}

static void pcs_remote_to_dev_set(pcs_dev_var_t *var, const char *service)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    cJSON *tag_data;
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
        {
            if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, service) == 0)
            {
                dbg_syslog(LOG_DEBUG, "mode set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                {
                    if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, service) == 0)
                    {

                        tag_data = cJSON_CreateObject();
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].remote); // 设置充放电模式
                        data_tmp = cJSON_Print(tag_data);
                        publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
    }
}

static void pcs_chargemode_to_dev_set(pcs_dev_var_t *var, const char *service)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    cJSON *tag_data;
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
        {
            if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, service) == 0)
            {
                dbg_syslog(LOG_DEBUG, "mode set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                {
                    if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, service) == 0)
                    {

                        tag_data = cJSON_CreateObject();
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, PCS_CHAREG_MODE_CONSTANT_POWER); // 设置充放电模式
                        data_tmp = cJSON_Print(tag_data);
                        publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
    }
}

static void pcs_openoff_to_dev_set(pcs_dev_var_t *var, const char *service)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};
    CHAR openFlag = 0;
    if (strcmp("open", service) == 0)
    {
        openFlag = 1;
    }
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {

        // if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.state == 0 && openFlag == 1)
        if (openFlag == 1)
        {
            dbg_syslog(LOG_DEBUG, "num:%d openoff is open", i);
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.state = 1;
        }
        // else if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.state == 1 && openFlag == 0)
        else if (openFlag == 0)
        {
            dbg_syslog(LOG_DEBUG, "num:%d openoff is close", i);
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.state = 0;
        }
        for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
        {
            if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, service) == 0)
            {
                dbg_syslog(LOG_DEBUG, "openoff set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                {
                    if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, service) == 0)
                    {
                        tag_data = cJSON_CreateObject();
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                        if (openFlag == 1)
                        {
                            cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].on); // 设置开机
                        }
                        else
                        {
                            cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].off); // 设置关机
                        }

                        data_tmp = cJSON_Print(tag_data);
                        publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
        dbg_syslog(LOG_DEBUG, "num:%d %s", j, service);
    }
}

static void pcs_reset_to_dev_set(pcs_dev_var_t *var,const char *service)
{
    int i, j, n;
    CHAR *data_tmp = NULL;
    int err = 1, num = 0;
    cJSON *tag_data;
    CHAR tagNode[64] = {0};
    CHAR openFlag = 0;
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        for (j = 0; j < var->devNodeInfo.servicetodevcont; j++)
        {
            if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].name, service) == 0)
            {
                dbg_syslog(LOG_DEBUG, "openoff set id:%s", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                for (n = 0; n < var->devNodeInfo.pserviceInfoTodev[j].tagNode.nodecont; n++)
                {
                    if (strcmp(var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].name, service) == 0)
                    {
                        tag_data = cJSON_CreateObject();
                        cJSON_AddStringToObject(tag_data, "sn", var->devNodeInfo.pdevnodecfg[i].devSn);
                        cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
                        cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
                        cJSON_AddStringToObject(tag_data, "identifier", var->devNodeInfo.pserviceInfoTodev[j].identifier);
                        cJSON_AddNumberToObject(tag_data, var->devNodeInfo.pserviceInfoTodev[j].tagNode.ptagNode[n].tag, var->pcs_type_operate[var->pcsType].reset); // pcs 复位
                        data_tmp = cJSON_Print(tag_data);
                        publish_to_dev_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pdevnodecfg[i].type);
                        free(data_tmp);
                        cJSON_Delete(tag_data);
                    }
                }
            }
        }
        dbg_syslog(LOG_DEBUG, "num:%d %s", j, service);
    }
}

static void pcs_open_set(pcs_dev_var_t *var)
{
    pcs_openoff_to_dev_set(var, "open");
    dbg_syslog(LOG_DEBUG, "pcs: open");
}

static void pcs_close_set(pcs_dev_var_t *var)
{
    pcs_openoff_to_dev_set(var, "close");
    dbg_syslog(LOG_DEBUG, "pcs:close");
}
static void pcs_mode_set(pcs_dev_var_t *var)
{
    pcs_chargemode_to_dev_set(var, "mode");
    dbg_syslog(LOG_DEBUG, "pcs:mode");
}
static void pcs_remote_set(pcs_dev_var_t *var)
{
    pcs_remote_to_dev_set(var, "remote");
    dbg_syslog(LOG_DEBUG, "pcs:remote");
}

static void pcs_reset(pcs_dev_var_t *var)
{
    pcs_reset_to_dev_set(var,"reset");
}

#define DI_CACHE_FILE "/tmp/pcserr.log"
char string[1024];

static void pcs_dev_entry(void *obj)
{
    int ret = -1, maxfd;
    fd_set rset;
    struct timeval timeout;
    char string[1024];
    while (1)
    {
        SELECT_INIT();
        // SELECT_ADD_FD(var->second_period_timer);
        timeout.tv_usec = 0;
        timeout.tv_sec = 5;
        ret = select(maxfd + 1, &rset, 0, 0, &timeout);
        if (ret < 0)
        {
            dbg_syslog(LOG_DEBUG, "errno %d\n", errno);

            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                dbg_syslog(LOG_DEBUG, "errno---");
                snprintf(string, sizeof(string), "erron %s  \n\r", strerror(errno));
                write_file_data(DI_CACHE_FILE, string, strlen(string));
                break;
            }
        }
    }
}

static int pcs_dev_state_change(void *obj, int state)
{
    pcs_dev_var_t *var = (pcs_dev_var_t *)obj;
    char topic[TOPIC_MAX_LEN] = {0};

    switch (state)
    {
    case MQTT_CONNECTED:
        snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/+/device/%s/start", var->sn_str, "pcs_dev_virtual");
        ipc_session_publish(var->session, topic, "", 0);
        break;
    }
    return E_TRUE;
}

static int publish_pcs_data(ipc_session_t *session, char *sn, unsigned char *data, int len, char *desSn, char *identifier)
{
    char topic[TOPIC_MAX_LEN] = {0};
    // ipc/%s/+/device/+/data/set_rglt_raw
    snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/%s/device/%s/data/service/%s", sn, "aaa", desSn, identifier);
    dbg_syslog(LOG_DEBUG, "topic:%s", topic);
    ipc_session_publish(session, topic, data, len);
    return 0;
}

static int publish_to_dev_data(ipc_session_t *session, char *sn, unsigned char *data, int len, char *desSn, char *porttype)
{
    char topic[TOPIC_MAX_LEN] = {0};
    // ipc/%s/+/device/+/data/set_rglt_raw
    snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/%s/device/%s/data/Set_Rglt", sn, porttype, desSn);
    dbg_syslog(LOG_DEBUG, "topic:%s", topic);
    ipc_session_publish(session, topic, data, len);
    return 0;
}

static int pcs_dev_report_alarm(pcs_dev_var_t *var, char *identifier)
{
    CHAR *data_tmp = NULL;
    int i, err = 1, num = 0;
    cJSON *sub = NULL;
    CHAR tagNode[64] = {0};
    cJSON *tag_data = cJSON_CreateObject();
    for (i = 0; i < var->devNodeInfo.devcont; i++)
    {
        if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.errState == 0)
        {
            err = 0;
        }
    }
    cJSON_AddStringToObject(tag_data, "sn", var->vir_sn_str);
    cJSON_AddNumberToObject(tag_data, "timestamp", time(NULL));
    cJSON_AddStringToObject(tag_data, "identifier", identifier);
    cJSON_AddNumberToObject(tag_data, "mi", PCS_MI);
    sprintf(tagNode, "{\"pcsalarm\":%d}", err);
    cJSON_AddStringToObject(tag_data, "tag_node", tagNode);
    data_tmp = cJSON_Print(tag_data);
    publish_pcs_data(var->session, var->sn_str, data_tmp, strlen(data_tmp), var->desSn, identifier);
    free(data_tmp);
    cJSON_Delete(tag_data);
}

static int pcs_dev_mqtt_handle_recv_msg(void *obj, ipc_msg_t *mqtt_msg)
{
    cJSON *node = NULL;
    cJSON *sub = NULL;
    CHAR *tagNode = NULL;
    int i, n, j = 0;
    int tmp = 0;
    double tmp1 = 0;
    pcs_dev_var_t *var = (pcs_dev_var_t *)obj;
    dbg_syslog(LOG_DEBUG, "topic:%s", mqtt_msg->topic);
    if (strstr(mqtt_msg->topic, "data/service"))
    {
        node = cJSON_Parse(mqtt_msg->payload);
        if (!node)
        {
            return E_FALSE;
        }
        GET_JSON_VALUE_INT(node, "mi", var->servInfo.mi);
        GET_JSON_VALUE_INT(node, "timestamp", var->servInfo.timestamp);
        GET_JSON_VALUE_STRING(node, "identifier", var->servInfo.identifier);
        GET_JSON_VALUE_STRING(node, "sn", var->servInfo.devSn);
        GET_JSON_VALUE_DY_STRING(node, "tag_node", tagNode);
        dbg_syslog(LOG_DEBUG, "mi:%d timestamp:%d identifier:%s sn:%s SERVICEUPCONT:%d tagNode:%s\r\n", var->servInfo.mi,var->servInfo.timestamp,var->servInfo.identifier,var->servInfo.devSn,SERVICEUPCONT,tagNode);
        if (tagNode != NULL)
        {
            sub = cJSON_Parse(tagNode);
            if (sub)
            {
                for (i = 0; i < SERVICEUPCONT; i++)
                {
                    if (strcmp(SERVICE_UP[i].identifier, var->servInfo.identifier) == 0)
                    {
                        for (j = 0; j < var->devNodeInfo.devcont; j++)
                        {
                            if (strcmp(var->devNodeInfo.pdevnodecfg[j].devSn, var->servInfo.devSn) == 0)
                            {
                                if (SERVICE_UP[i].tagNode.nodecont > 0)
                                {
                                    for (n = 0; n < SERVICE_UP[i].tagNode.nodecont; n++)
                                    {
                                        tmp = -1;
                                        GET_JSON_VALUE_INT_LOG(sub, SERVICE_UP[i].tagNode.ptagNode[n].tag, tmp);
                                        if (tmp != -1)
                                        {
                                            dbg_syslog(LOG_DEBUG, "tag name:%s", SERVICE_UP[i].tagNode.ptagNode[n].name);
                                            if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "fault") == 0)
                                            {
                                                var->devNodeInfo.pdevnodecfg[j].pcsInfo.errState = tmp;
                                                pcs_dev_report_alarm(var, SERVICE_UP[i].inidentifier);
                                            }
                                            else if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "connect") == 0)
                                            {
                                                var->devNodeInfo.pdevnodecfg[j].pcsInfo.connect = tmp;
                                                dbg_syslog(LOG_DEBUG, "connect set i:%d ", j, var->devNodeInfo.pdevnodecfg[j].pcsInfo.connect);
                                            }
                                            else if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "disconnect") == 0)
                                            {
                                                var->devNodeInfo.pdevnodecfg[j].pcsInfo.connect = tmp == 1 ? 0 : 1;
                                                dbg_syslog(LOG_DEBUG, "disconnect set i:%d ", j, var->devNodeInfo.pdevnodecfg[j].pcsInfo.connect);
                                            }
                                            else if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "conenable") == 0)
                                            {
                                                var->devNodeInfo.pdevnodecfg[j].pcsInfo.conenable = tmp;
                                            }
                                            else if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "remote") == 0)
                                            {
                                                if (tmp == 0)
                                                {
                                                    if (var->pcsType == 1)
                                                    {
                                                        pcs_remote_set(var);
                                                    }
                                                }
                                            }
                                            else if (strcmp(SERVICE_UP[i].tagNode.ptagNode[n].name, "stop") == 0)
                                            {
                                                dbg_syslog(LOG_DEBUG, "tmp:%d i:%d state:%d", tmp, i, var->devNodeInfo.pdevnodecfg[i].pcsInfo.state);
                                                if (tmp == 1)
                                                {
                                                    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.state == 1)
                                                    {
                                                        pcs_open_set(var);
                                                    }
                                                }
                                                else if(tmp == 0)
                                                {
                                                    if (var->devNodeInfo.pdevnodecfg[i].pcsInfo.state == 0)
                                                    {
                                                        pcs_close_set(var);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                cJSON_Delete(sub);
            }
            free(tagNode);
        }
    }
    else if (strstr(mqtt_msg->topic, "data/set_rglt_raw"))
    {
        node = cJSON_Parse(mqtt_msg->payload);
        if (!node)
        {
            return E_FALSE;
        }
        GET_JSON_VALUE_INT(node, "mi", var->servInfo.mi);
        GET_JSON_VALUE_INT(node, "timestamp", var->servInfo.timestamp);
        GET_JSON_VALUE_STRING(node, "identifier", var->servInfo.identifier);
        GET_JSON_VALUE_STRING(node, "sn", var->servInfo.devSn);
        dbg_syslog(LOG_DEBUG, "mi:%d timestamp:%d identifier:%s sn:%s SERVICEDOWNCONT:%d\r\n", var->servInfo.mi,var->servInfo.timestamp,var->servInfo.identifier,var->servInfo.devSn,SERVICEDOWNCONT);

        for (i = 0; i < SERVICEDOWNCONT; i++)
        {
            dbg_syslog(LOG_DEBUG, "i:%d identifier:%s name:%s", i, SERVICE_DOWN[i].identifier, SERVICE_DOWN[i].name);
            if (strcmp(SERVICE_DOWN[i].identifier, var->servInfo.identifier) == 0)
            {
                if (strcmp(SERVICE_DOWN[i].name, "p2") == 0)
                {
                    GET_JSON_VALUE_DOUBLE_LOG(node, "p2", tmp1);
                    pcs_power_set(tmp1, var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "wggl") == 0)
                {
                    GET_JSON_VALUE_INT_LOG(node, "wggl", tmp);
                    pcs_wggl_set(tmp, var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "connect") == 0)
                {
                    pcs_connect_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "disconnect") == 0)
                {
                    pcs_disconnect_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "on") == 0)
                {
                    pcs_open_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "off") == 0)
                {
                    pcs_close_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "mode") == 0)
                {
                    pcs_mode_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "remote") == 0)
                {
                    pcs_remote_set(var);
                }
                else if (strcmp(SERVICE_DOWN[i].name, "reset") == 0)
                {
                    pcs_reset(var);
                }
            }
        }
    }

    if (node)
    {
        cJSON_Delete(node);
    }
    return 0;
}

static void pcs_dev_subscribe_all(pcs_dev_var_t *var)
{
    CHAR topic[TOPIC_MAX_LEN] = {0};
    int i, j;
    if (var->runMode == 0)
    {
        snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/+/device/%s/data/set_rglt_raw", var->sn_str, var->vir_sn_str);
        dbg_syslog(LOG_DEBUG, "topic:%s\r\n", topic);
        ipc_session_subscribe(var->session, topic);

        for (i = 0; i < var->devNodeInfo.devcont; i++)
        {
            for (j = 0; j < var->devNodeInfo.serviceupcont; j++)
            {
                snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/+/device/%s/data/service/%s", var->sn_str, var->devNodeInfo.pdevnodecfg[i].devSn, var->devNodeInfo.pserviceInfoUP[j].identifier);
                dbg_syslog(LOG_DEBUG, "topic:%s\r\n", topic);
                ipc_session_subscribe(var->session, topic);
            }
        }
    }
    else
    {
    }
}

static int pcs_dev_mqtt_client_init(pcs_dev_var_t *var)
{
    char clientId[MAX_CLIENT_ID_LEN] = {0};
    snprintf(clientId, MAX_CLIENT_ID_LEN, "INT_pcs_dev_%s", var->sn_str);
    var->session = ipc_session_new(clientId, (void *)var, IPC_DEFAULT);

    if (var->session == NULL)
        return -1;

    if (var->runMode != 0)
    {
        ipc_session_set_address(var->session, var->mqttInfo.hostname, var->mqttInfo.port, var->mqttInfo.username, var->mqttInfo.password);
    }
    ipc_session_set_callbacks(var->session, pcs_dev_mqtt_handle_recv_msg, pcs_dev_state_change);
    pcs_dev_subscribe_all(var);
    ipc_session_start(var->session);
    sleep(5);
    if (var->pcsType == 1)
    {
        pcs_remote_set(var);
    }
    return E_TRUE;
}

static int load_pcs_dev_cfg(pcs_dev_var_t *var, const char *cfg_file)
{
    CHAR *pdata = NULL;
    cJSON *root = NULL;
    cJSON *nodes = NULL;
    cJSON *node = NULL;
    cJSON *tmp = NULL;
    int node_cnt = 0, i = 0;
    BYTE flag = E_TRUE;

    if (var == NULL || cfg_file == NULL)
    {
        dbg_syslog(LOG_ERR, "pcfg:%p cfg_file:%p", var, cfg_file);
        return -1;
    }
    pdata = read_file_data(cfg_file);

    if (pdata == NULL)
    {
        dbg_syslog(LOG_ERR, "read cfg file %s error", cfg_file);
        flag = E_FALSE;
        goto out;
    }
    root = cJSON_Parse(pdata);
    if (!root)
    {
        dbg_syslog(LOG_ERR, "parse cfg file %s error", cfg_file);
        flag = E_FALSE;
        goto out;
    }
    GET_JSON_VALUE_STRING_LOG(root, "devSn", var->vir_sn_str);
    GET_JSON_VALUE_STRING_LOG(root, "desSn", var->desSn);
    GET_JSON_VALUE_INT_LOG(root, "runMode", var->runMode);
    GET_JSON_VALUE_INT_LOG(root, "pcsType", var->pcsType);
    nodes = cJSON_GetObjectItemCaseSensitive(root, "node");

    if (!nodes)
    {
        dbg_syslog(LOG_ERR, "get node failed");
        flag = E_FALSE;
        goto out;
    }

    node_cnt = cJSON_GetArraySize(nodes);
    if (node_cnt != 0)
    {
        var->devNodeInfo.pdevnodecfg = (DEV_NODE_CFG_T *)malloc(node_cnt * sizeof(DEV_NODE_CFG_T));

        if (var->devNodeInfo.pdevnodecfg == NULL)
        {
            dbg_syslog(LOG_ERR, "malloc pdevnodcfg failed,node_cnt:%d", node_cnt);
            flag = E_FALSE;
            goto out;
        }
        memset(var->devNodeInfo.pdevnodecfg, 0, node_cnt * sizeof(DEV_NODE_CFG_T));
        var->devNodeInfo.devcont = node_cnt;
        for (i = 0; i < node_cnt; i++)
        {
            node = cJSON_GetArrayItem(nodes, i);
            GET_JSON_VALUE_STRING_LOG(node, "devSn", var->devNodeInfo.pdevnodecfg[i].devSn);
            GET_JSON_VALUE_STRING_LOG(node, "type", var->devNodeInfo.pdevnodecfg[i].type);
            GET_JSON_VALUE_INT_LOG(node, "maxChar", var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxChargeP);
            GET_JSON_VALUE_INT_LOG(node, "maxDischar", var->devNodeInfo.pdevnodecfg[i].pcsInfo.maxDischarP);
            var->devNodeInfo.pdevnodecfg[i].pcsInfo.state = 0xff;
        }
    }
    nodes = cJSON_GetObjectItemCaseSensitive(root, "service_down");
    if (!nodes)
    {
        dbg_syslog(LOG_ERR, "get service_down failed");
        flag = E_FALSE;
        goto out;
    }
    node_cnt = cJSON_GetArraySize(nodes);
    if (node_cnt != 0)
    {
        var->devNodeInfo.pserviceInfoDOWN = (SERVICE_INFO_T *)malloc(node_cnt * sizeof(SERVICE_INFO_T));
        if (var->devNodeInfo.pserviceInfoDOWN == NULL)
        {
            dbg_syslog(LOG_ERR, "malloc pserviceInfoDOWN failed,node_cnt:%d", node_cnt);
            flag = E_FALSE;
            goto out;
        }
        var->devNodeInfo.servicedowncont = node_cnt;
        for (i = 0; i < node_cnt; i++)
        {
            node = cJSON_GetArrayItem(nodes, i);
            GET_JSON_VALUE_STRING_LOG(node, "identifier", var->devNodeInfo.pserviceInfoDOWN[i].identifier);
            GET_JSON_VALUE_STRING_LOG(node, "name", var->devNodeInfo.pserviceInfoDOWN[i].name);
        }
    }
    nodes = cJSON_GetObjectItemCaseSensitive(root, "service_up");
    if (!nodes)
    {
        dbg_syslog(LOG_ERR, "get service_up failed");
        flag = E_FALSE;
        goto out;
    }
    node_cnt = cJSON_GetArraySize(nodes);
    if (node_cnt != 0)
    {
        var->devNodeInfo.pserviceInfoUP = (SERVICE_INFO_T *)malloc(node_cnt * sizeof(SERVICE_INFO_T));
        if (var->devNodeInfo.pserviceInfoUP == NULL)
        {
            dbg_syslog(LOG_ERR, "malloc pserviceInfoDOWN failed,node_cnt:%d", node_cnt);
            flag = E_FALSE;
            goto out;
        }
        var->devNodeInfo.serviceupcont = node_cnt;
        for (i = 0; i < node_cnt; i++)
        {
            node = cJSON_GetArrayItem(nodes, i);
            GET_JSON_VALUE_STRING_LOG(node, "identifier", var->devNodeInfo.pserviceInfoUP[i].identifier);
            GET_JSON_VALUE_STRING_LOG(node, "inidentifier", var->devNodeInfo.pserviceInfoUP[i].inidentifier);
            GET_JSON_VALUE_STRING_LOG(node, "name", var->devNodeInfo.pserviceInfoUP[i].name);
            {
                int j, tagcon = 0;
                cJSON *tagnodes = NULL;
                cJSON *tagnode = NULL;
                tagnodes = cJSON_GetObjectItemCaseSensitive(node, "tagnode");
                if (!tagnode)
                {
                    // todo 是否需要判断加载失败退出
                    tagcon = cJSON_GetArraySize(tagnodes);
                    dbg_syslog(LOG_ERR, "tagcon:%d", tagcon);
                    var->devNodeInfo.pserviceInfoUP[i].tagNode.ptagNode = (TAG_NODE_T *)malloc(tagcon * sizeof(TAG_NODE_T));
                    if (var->devNodeInfo.pserviceInfoUP[i].tagNode.ptagNode == NULL)
                    {
                        flag = E_FALSE;
                        goto out;
                    }
                    var->devNodeInfo.pserviceInfoUP[i].tagNode.nodecont = tagcon;
                    for (j = 0; j < tagcon; j++)
                    {
                        tagnode = cJSON_GetArrayItem(tagnodes, j);
                        GET_JSON_VALUE_STRING_LOG(tagnode, "tag", var->devNodeInfo.pserviceInfoUP[i].tagNode.ptagNode[j].tag);
                        GET_JSON_VALUE_STRING_LOG(tagnode, "name", var->devNodeInfo.pserviceInfoUP[i].tagNode.ptagNode[j].name);
                    }
                }
            }
        }
    }

    nodes = cJSON_GetObjectItemCaseSensitive(root, "service_todev");
    if (!nodes)
    {
        dbg_syslog(LOG_ERR, "get service_todev failed");
        flag = E_FALSE;
        goto out;
    }
    node_cnt = cJSON_GetArraySize(nodes);
    if (node_cnt != 0)
    {
        var->devNodeInfo.pserviceInfoTodev = (SERVICE_INFO_T *)malloc(node_cnt * sizeof(SERVICE_INFO_T));
        if (var->devNodeInfo.pserviceInfoTodev == NULL)
        {
            dbg_syslog(LOG_ERR, "malloc pserviceInfoDOWN failed,node_cnt:%d", node_cnt);
            flag = E_FALSE;
            goto out;
        }
        var->devNodeInfo.servicetodevcont = node_cnt;
        for (i = 0; i < node_cnt; i++)
        {
            node = cJSON_GetArrayItem(nodes, i);
            GET_JSON_VALUE_STRING_LOG(node, "identifier", var->devNodeInfo.pserviceInfoTodev[i].identifier);
            GET_JSON_VALUE_STRING_LOG(node, "name", var->devNodeInfo.pserviceInfoTodev[i].name);
            {
                int j, tagcon = 0;
                cJSON *tagnodes = NULL;
                cJSON *tagnode = NULL;
                tagnodes = cJSON_GetObjectItemCaseSensitive(node, "tagnode");
                if (!tagnode)
                {
                    // todo 是否需要判断加载失败退出
                    tagcon = cJSON_GetArraySize(tagnodes);
                    dbg_syslog(LOG_ERR, "tagcon:%d", tagcon);
                    var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode = (TAG_NODE_T *)malloc(tagcon * sizeof(TAG_NODE_T));
                    if (var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode == NULL)
                    {
                        flag = E_FALSE;
                        goto out;
                    }
                    var->devNodeInfo.pserviceInfoTodev[i].tagNode.nodecont = tagcon;
                    for (j = 0; j < tagcon; j++)
                    {
                        tagnode = cJSON_GetArrayItem(tagnodes, j);
                        GET_JSON_VALUE_STRING_LOG(tagnode, "tag", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[j].tag);
                        GET_JSON_VALUE_STRING_LOG(tagnode, "name", var->devNodeInfo.pserviceInfoTodev[i].tagNode.ptagNode[j].name);
                    }
                }
            }
        }
    }
    nodes = cJSON_GetObjectItemCaseSensitive(root, "operate");
    if (!nodes)
    {
        dbg_syslog(LOG_ERR, "get operate failed");
        goto out;
    }
    node_cnt = cJSON_GetArraySize(nodes);
    if (node_cnt != 0)
    {
        if (node_cnt > PCS_TYPE_NUM)
        {
            goto out;
        }
        for (i = 0; i < node_cnt; i++)
        {
            node = cJSON_GetArrayItem(nodes, i);
            GET_JSON_VALUE_INT_LOG(node, "on", var->pcs_type_operate[i].on);
            GET_JSON_VALUE_INT_LOG(node, "off", var->pcs_type_operate[i].off);
            GET_JSON_VALUE_INT_LOG(node, "remote", var->pcs_type_operate[i].remote);
            GET_JSON_VALUE_INT_LOG(node, "open", var->pcs_type_operate[i].open);
            GET_JSON_VALUE_INT_LOG(node, "close", var->pcs_type_operate[i].close);
            GET_JSON_VALUE_INT_LOG(node, "reset", var->pcs_type_operate[i].reset);
        }
    }

out:
    cJSON_Delete(root);
    if (pdata != NULL)
    {
        free(pdata);
    }
    if (flag == E_FALSE)
    {
        if (var->devNodeInfo.pdevnodecfg != NULL)
        {
            free(var->devNodeInfo.pdevnodecfg);
        }
        if (var->devNodeInfo.pserviceInfoDOWN != NULL)
        {
            free(var->devNodeInfo.pserviceInfoDOWN);
        }
        if (var->devNodeInfo.pserviceInfoTodev != NULL)
        {
            free(var->devNodeInfo.pserviceInfoTodev);
        }
        if (var->devNodeInfo.pserviceInfoUP != NULL)
        {
            free(var->devNodeInfo.pserviceInfoUP);
        }
    }
    return 0;
}

static void nodes_cfg_show(nodes_cfg_table_t *nodes_table)
{
    int i;
    CHAR *token;
    dbg_syslog(LOG_ERR, "node_cnt:%d", nodes_table->node_cnt);
    for (i = 0; i < nodes_table->node_cnt; i++)
    {
        token = strtok(nodes_table->node[i].sn, "_");
        dbg_syslog(LOG_ERR, "tocken:%s", token);
        token = strtok(NULL, "_");
        dbg_syslog(LOG_ERR, "tocken:%s product_key:%s sn:%s template_id:%s", token, nodes_table->node[i].product_key,
                  nodes_table->node[i].sn,
                  nodes_table->node[i].template_id);
    }
}

static void templates_cfg_show(template_table_t *temp_table)
{
    int i, j;
    dbg_syslog(LOG_ERR, "template_cnt:%d", temp_table->template_cnt);
    for (i = 0; i < temp_table->template_cnt; i++)
    {
        dbg_syslog(LOG_ERR, "template_id:%s", temp_table->template[i].template_id);
        if (temp_table->template[i].service_tab != NULL)
        {
            for (j = 0; j < temp_table->template[i].service_tab->serviceCnt; j++)
            {
                dbg_syslog(LOG_ERR, "identifier:%s ", temp_table->template[i].service_tab->service[j].identifier);
            }
        }
    }
}

static void data_show(object_property_table_t *object_property, CHAR *director)
{
    int i;
    dbg_syslog(LOG_ERR, "propertyCnt:%d directoc->%s", object_property->propertyCnt, director);
    for (i = 0; i < object_property->propertyCnt; i++)
    {
        dbg_syslog(LOG_ERR, "identifier:%s ", object_property->property[i].identifier);
    }
}

static void service_tab_show(object_service_table_t *object_service_table)
{
    int i;
    dbg_syslog(LOG_ERR, "serviceCnt:%d", object_service_table->serviceCnt);
    for (i = 0; i < object_service_table->serviceCnt; i++)
    {
        dbg_syslog(LOG_ERR, "i:%d identifier:%s", i, object_service_table->service[i].identifier);
        if (object_service_table->service[i].pinput != NULL)
        {

            data_show(object_service_table->service[i].pinput, "inputdata");
        }
        if (object_service_table->service[i].poutput != NULL)
        {
            data_show(object_service_table->service[i].pinput, "outputdata");
        }
    }
}

static void object_cfg_show(object_table_t *object_table)
{
    int i;
    dbg_syslog(LOG_ERR, "object_cnt:%d", object_table->object_cnt);
    for (i = 0; i < object_table->object_cnt; i++)
    {
        dbg_syslog(LOG_ERR, "i:%d object_model_id:%s", i, object_table->object[i].object_model_id);
        if (object_table->object[i].service_tab->serviceCnt != 0)
        {
            service_tab_show(object_table->object[i].service_tab);
        }
    }
}

static void pcs_dev_init(void *obj)
{
    int ret;
    pcs_dev_var_t *var = (pcs_dev_var_t *)obj;
    ret = load_pcs_dev_cfg(var, PCS_DEV_FILE);
    if (ret != 0)
    {
        dbg_syslog(LOG_DEBUG, "load_pcs_dev_cfg fail:file name->%s", PCS_DEV_FILE);
    }
    get_board_sn(var->sn_str); // 所有表信息;meter  sn
    dbg_syslog(LOG_DEBUG, "board SN:%s", var->sn_str);

    pcs_dev_mqtt_client_init(var);
}

void main()
{
    pcs_dev_var_t pcs_dev_var = {0};
    lnxall_loglevel_set(LNXALL_LOGNOTICE,1);
    pcs_dev_init(&pcs_dev_var);
    pcs_dev_entry(&pcs_dev_var);
}