/******************************************************************
** Copyright (c) 2009  Wuhan xiyun Technology Co., Ltd .
** FileName:	cmd.c
** Author:	 	chw
** Mail:		
** Editor:		chw
** Date:		2020-12-03 13:34
** Version: 	2020-12-03
** File Description:  mqtt 服务发送业务指令实现
** Param explain: char* mac : 网关MAC地址
   char* subMac             ：子节点MAC地址
  MQTTAsync_message *pubmsg : 消息结构体
  MYSQL *_db                ：数据库连接
******************************************************************/

#include "core.h"
#include "cmd.h"

//时间同步
int  SendNTP(char *mac)
{
    //获取系统时间
    time_t timep;
    struct tm *p;
    time(&timep);
    p = gmtime(&timep);
    int year2 = (p->tm_year+1900)%100;
    int mon = p->tm_mon + 1;
    int day = p->tm_mday;
    int hour = p->tm_hour + 8;
    int minc = p->tm_min;
    int sec = p->tm_sec;

    //debug("%s 2时间同步发送结果",mac);

    //填充报文
    char buf[10] = {0};
    buf[0] = (char)year2;
    buf[1] = (char)mon;
    buf[2] = (char)day;
    buf[3] = (char)hour;
    buf[4] = (char)minc;
    buf[5] = (char)sec;
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    sendData.payload = buf;
    sendData.payloadlen = 6;
    sendData.qos = 0;
    sendData.retained = 0;

    //主题
    char topicName[256];
    if(strcmp(mac,"") == 0)
    {
        sprintf(topicName,"NTP");
    }
    else
    {
        sprintf(topicName,"PP/%s/CFG/NTP",mac);
    }

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送时间同步指令,结果:%d,时间:%d-%d-%d %d:%d:%d,主题:%s \n",ret,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],topicName);
    return ret;
}

//校验协议长度
int CheckMsgLength(char *topicName,MQTTAsync_message *pubmsg,int protocal_length)
{
    UNUSED(topicName);
    if(pubmsg->payloadlen != protocal_length)
    {
        unsigned char* p = pubmsg->payload;

        if(pubmsg->payloadlen < 512)
        {
            char pdata[1024] = {0};
            Hex2Str((const char*)p,pdata,pubmsg->payloadlen);
            elog("error len--topicName:%s payloadlen:%d,msg:%s\n",topicName,pubmsg->payloadlen,pdata);
        }
        else
        {
            elog("error len--topicName:%s payloadlen:%d,msg:数据大于512\n",topicName,pubmsg->payloadlen);
        }

        return 1;
    }

    return 0;
}

//备份服务器ip发送
int SendBakIP(char *mac , MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    char ip[20] = {0};
    int  bakport = 0;
    char buf[256] = {0};
    char sendPrint[256] = {0};

    
    //数据库查询
    sprintf(query,"select bak_ip,bak_port from dev_info_gateway where device_mac ='%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s bak_ip 或者 bak_port 为空 \n",mac);
        mysql_free_result(res);
        return 1;
    }
    strcpy(ip,row[0]);
    bakport = atoi(row[1]);
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/BKS",mac);

    //填充报文
    unsigned long lIP = inet_addr(ip);
    memcpy(buf,&lIP,4);
    buf[4] = ((char*)&bakport)[1];
    buf[5] = ((char*)&bakport)[0];
    sendData.payload = buf;
    sendData.payloadlen = 6;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    Hex2Str(buf,sendPrint,sendData.payloadlen);
    log(" ↓发送备份服务器ip指令,结果:%d,网关:%s,ip:%s,bakport:%d,报文:%s \n",ret,mac,ip,bakport,sendPrint);
    
    return ret;
}

//节点信息表发送
int SendSubInfo(char *mac , MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char buf[256] = {0};
    char topicName[256];
    char sendPrint[256] = {0};
    int row_count;
    int ret = 0;
    
    //数据库查询
    sprintf(query,"select device_mac,device_type from dev_info_node where gateway_mac ='%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    //获取行数
    row_count = mysql_num_rows(res);
    if(row_count<1)
    {
        log("%s 没有查询到子节点 \n",mac);
        mysql_free_result(res);
        return 1;
    }
    //循环取出
    int i = 0;
    buf[0] = row_count;
    for (i = 0; i < row_count; i++)
    {
        char subMac[30] = {0};
        unsigned char nodeMac[30] = {0};
        int noteType = 0;
        row = mysql_fetch_row(res);
        if(!row[0] || !row[1])
        {
            log("%s 节点mac或者类型为空 \n",mac);
            continue;    
        }
        strcpy(subMac,row[0]);//子节点
        HexStrToByte(subMac,nodeMac,12);
        noteType = atoi(row[1]);//节点类型
        memcpy(buf+1+7*i,nodeMac,6);
        buf[1+7*i+6] = noteType;
    }
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/NAT",mac);

    //填充报文
    sendData.payload = buf;
    sendData.payloadlen = row_count*7 + 1;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    ret = my_mqqta_sendmsg(topicName, &sendData);
    Hex2Str(buf,sendPrint,sendData.payloadlen);
    log(" ↓发送节点信息表指令,结果:%d,网关:%s,报文:%s \n",ret,mac,sendPrint);

    return ret;
}

//额定电压发送
int SendRatedVoltage(char *mac,char *subMac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    unsigned char buf[256] = {0};
    unsigned char nodeMac[30] = {0};
    char topicName[256];
    int rated_voltage;
    int device_type;

    //数据库查询
    if (strcmp(subMac,"") == 0) //网关
    {
        sprintf(query,"select rated_voltage,device_type from dev_info_gateway where device_mac ='%s'",mac);
        HexStrToByte("0F0000000001",nodeMac,12);
    }
    else
    {
        sprintf(query,"select rated_voltage,device_type from dev_info_node where device_mac ='%s'",subMac);
        HexStrToByte(subMac,nodeMac,12);
    }
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s 额定电压或者设备类型为空 \n",mac);
        mysql_free_result(res);
        return 1;
    }
    rated_voltage = (atof(row[0]))*100;
    if (strcmp(subMac,"") == 0) //网关
    {
        device_type = 2;
    }
    else
    {
        device_type = atoi(row[1]);
    }
    mysql_free_result(res);
    debug("数据库查询:rated_voltage:%d,device_type:%d \n",rated_voltage,device_type);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/SRV",mac);
    //填充报文
    memcpy(buf,nodeMac,6);
    buf[6] = device_type;
    buf[7] = ((char*)&rated_voltage)[1];
    buf[8] = ((char*)&rated_voltage)[0];
    sendData.payload = buf;
    sendData.payloadlen = 9;
    sendData.qos = 0;
    sendData.retained = 0;
    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送额定电压设置指令,结果:%d,网关:%s,节点:%s,额定电压:%d,设备类型:%d \n",ret,mac,subMac,rated_voltage,device_type);

    return ret;
}

//额定电流发送
int SendRatedCurrent(char *mac,char *subMac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    unsigned char buf[256] = {0};
    unsigned char nodeMac[30] = {0};
    char topicName[256];
    int rated_current;
    int device_type;

    //数据库查询
    if (strcmp(subMac,"") == 0) //网关
    {
        sprintf(query,"select rated_current,device_type from dev_info_gateway where device_mac ='%s'",mac);
        HexStrToByte("0F0000000001",nodeMac,12);
    }
    else
    {
        sprintf(query,"select rated_current,device_type from dev_info_node where device_mac ='%s'",subMac);
        HexStrToByte(subMac,nodeMac,12);
    }
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s 额定电流或者设备类型为空 \n",mac);
        mysql_free_result(res);
        return 1;
    }
    rated_current = (atof(row[0]))*10000;
    if (strcmp(subMac,"") == 0) //网关
    {
        device_type = 2;
    }
    else
    {
        device_type = atoi(row[1]);
    }
    mysql_free_result(res);
    debug("数据库查询:rated_current:%d,device_type:%d \n",rated_current,device_type);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/SRC",mac);
    //填充报文
    memcpy(buf,nodeMac,6);
    buf[6] = device_type;
    buf[7] = ((char*)&rated_current)[3];
    buf[8] = ((char*)&rated_current)[2];
    buf[9] = ((char*)&rated_current)[1];
    buf[10] = ((char*)&rated_current)[0];
    sendData.payload = buf;
    sendData.payloadlen = 11;
    sendData.qos = 0;
    sendData.retained = 0;
    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送额定电流设置指令,结果:%d,网关:%s,节点:%s,额定电流:%d,设备类型:%d \n",ret,mac,subMac,rated_current,device_type);
    
    return ret;
}

/*
//传感器阈值发送
int SendBakIP(char *mac)
{
    return 0;
} */

//远程重启
int SendRestart(char *mac)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    char topicName[256];

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RRS",mac);
    sendData.payload = NULL;
    sendData.payloadlen = 0;
    sendData.qos = 0;
    sendData.retained = 0;
    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送远程重启指令,结果:%d,网关:%s \n",ret,mac);
    
    return ret;
}

//设备恢复出厂设置
int SendFactoryReset(char *mac)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    char topicName[256];

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/SFR",mac);
    sendData.payload = NULL;
    sendData.payloadlen = 0;
    sendData.qos = 0;
    sendData.retained = 0;
    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送设备恢复出厂设置指令,结果:%d,网关:%s \n",ret,mac);

    return ret;
}

//服务器跳转
int SendServerJump(char *mac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    char jump_ip[20] = {0};
    int  jump_port = 0;
    char buf[256] = {0};

    
    //数据库查询
    sprintf(query,"select jump_ip,jump_port from dev_info_gateway where device_mac ='%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s jump_ip 或者 jump_port 为空",mac);
        mysql_free_result(res);
        return 1;
    }
    strcpy(jump_ip,row[0]);
    jump_port = atoi(row[1]);
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RS",mac);

    //填充报文
    unsigned long lIP = inet_addr(jump_ip);
    memcpy(buf,&lIP,4);
    buf[4] = ((char*)&jump_port)[1];
    buf[5] = ((char*)&jump_port)[0];
    sendData.payload = buf;
    sendData.payloadlen = 6;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送服务器跳转指令,结果:%d,网关:%s,jump_ip:%s,jump_port:%d \n",ret,mac,jump_ip,jump_port);
    
    return ret;
}


//ota升级
int SendRemoteUpgrade(char *mac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    char upgrade_ip[20] = {0};
    int  upgrade_port = 0;
    char ota_file[256] = {0};
    int  ota_mode = 0;
    char buf[256] = {0};
    
    //数据库查询
    sprintf(query,"select upgrade_ip,upgrade_port,file_name,ota_mode from dev_info_gateway where device_mac ='%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1] || !row[3] || !row[4])
    {
        log("%s upgrade_ip 或者 upgrade_port 为空 或者 file_name、ota_mode为空",mac);
        mysql_free_result(res);
        return 1;
    }
    strcpy(upgrade_ip,row[0]);
    upgrade_port = atoi(row[1]);
    strcpy(ota_file,row[2]);
    ota_mode = atoi(row[3]);
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/OTA",mac);

    //填充报文
    unsigned long lIP = inet_addr(upgrade_ip);
    memcpy(buf,&lIP,4);
    buf[4] = ((char*)&upgrade_port)[1];
    buf[5] = ((char*)&upgrade_port)[0];
    sendData.payload = buf;
    sendData.payloadlen = 6;
    sendData.qos = 0;
    sendData.retained = 0;

    //文件加入升级文件链表
    UpgradeFileAddFromDB(file_list,ota_file,_db,ota_mode);

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送服务器远程升级指令,结果:%d,网关:%s,upgrade_ip:%s,upgrade_port:%d,file_name:%s,ota_mode:%d \n",ret,mac,upgrade_ip,upgrade_port,ota_file,ota_mode);
    
    return ret;
}


//远程手动调光
int SendManualDimming(char* mac,int group,int luminance,int dimmingType)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    char topicName[256];
    char buf[256] = {0};

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RDC",mac);

    //填充报文
    buf[0] = group;
    buf[1] = luminance;
    buf[2] = dimmingType;
    sendData.payload = buf;
    sendData.payloadlen = 3;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送手动调光指令,结果:%d,网关:%s,组号:%d,亮度:%d,调光类型:%d \n",ret,mac,group,luminance,dimmingType);

    return ret;
}


//远程开关控制
int SendSwitchControl(char* mac,char* subMac,int type,int on_off)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    char topicName[256];
    char buf[256] = {0};
    unsigned char nodeMac[30] = {0};

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RSC",mac);

    //填充报文
    if(strcmp(subMac,"") == 0)
    {
        HexStrToByte("0F0000000001",nodeMac,12);
        memcpy(buf,nodeMac,6);
        buf[6] = 2;
        buf[7] = on_off;
    }
    else
    {
        HexStrToByte(subMac,nodeMac,12);
        memcpy(buf,nodeMac,6);
        buf[6] = type;
        buf[7] = on_off;
    }
    sendData.payload = buf;
    sendData.payloadlen = 8;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送远程开关控制指令,结果:%d,网关:%s,类型:%d,开关动作:%d\n",ret,mac,type,on_off);

    return ret;
}

//远程开关编组控制
int SendSwitchGroupControl(char* mac,int group,int type,int on_off)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    char topicName[256];
    char buf[256] = {0};

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RGC",mac);

    //填充报文
    buf[0] = group;
    buf[1] = type;
    buf[2] = on_off;
    sendData.payload = buf;
    sendData.payloadlen = 3;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送远程开关编组控制指令,结果:%d,网关:%s,组号:%d,类型:%d,开关动作:%d\n",ret,mac,group,type,on_off);

    return ret;
}


//删除子节点
int SendDeleteNode(char* mac,char* subMac,int nodeType)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    char topicName[256];
    char buf[256] = {0};
    unsigned char nodeMac[30] = {0};

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CTR/RCN",mac);

    //填充报文
    HexStrToByte(subMac,nodeMac,12);
    memcpy(buf,nodeMac,6);
    buf[6] = nodeType;
    sendData.payload = buf;
    sendData.payloadlen = 7;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送删除子节点指令,结果:%d,网关:%s,节点:%s,节点类型:%d \n",ret,mac,subMac,nodeType);

    return ret;
}


//设备数据上传间隔设置
int SendDataInterval(char* mac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int upload_interval_unit = 0;
    int upload_interval = 0;
    char buf[256] = {0};

    
    //数据库查询
    sprintf(query,"select upload_interval_unit,upload_interval from dev_info_gateway where device_mac ='%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s upload_interval_unit 或者 upload_interval 为空",mac);
        mysql_free_result(res);
        return 1;
    }
    upload_interval_unit = atoi(row[0]);
    upload_interval = atoi(row[1]);
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/ULI",mac);

    //填充报文
    buf[0] = upload_interval_unit;
    buf[1] = upload_interval;
    sendData.payload = buf;
    sendData.payloadlen = 2;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送设备数据上传间隔设置指令,结果:%d,网关:%s,上传间隔单位:%d,上传间隔:%d \n",ret,mac,upload_interval_unit,upload_interval);
    
    return ret;
}


//开关时间段设置
int SendOnOffTime(char* mac,char* subMac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int device_type = 0;
    char open_time[10] = {0};
    char close_time[10] = {0};
    int time1 = 0;
    int time2 = 0;
    int time3 = 0;
    int time4 = 0;
    char buf[256] = {0};
    unsigned char dMac[30] = {0};

    //判断网关 子节点
    if(strcmp(subMac,"") == 0) //网关
    {
        sprintf(query,"select device_type,open_time,close_time from dev_info_gateway where device_mac ='%s'",mac);
        HexStrToByte("0F0000000001",dMac,12);
    }
    else
    {
        sprintf(query,"select device_type,open_time,close_time from dev_info_node where device_mac ='%s'",subMac);
        HexStrToByte(subMac,dMac,12);
    }
    
    //数据库查询
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1] || !row[2])
    {
        log("%s device_type,open_time,close_time 为空",mac);
        mysql_free_result(res);
        return 1;
    }

    if (strcmp(subMac,"") == 0) //网关
    {
        device_type = 2;
    }
    else
    {
        device_type = atoi(row[0]);
    }
    strcpy(open_time,row[1]);
    strcpy(close_time,row[2]);
    mysql_free_result(res);
    time1 = atoi(strtok(open_time,":"));
    time2 = atoi(strtok(NULL,":"));
    time3 = atoi(strtok(close_time,":"));
    time4 = atoi(strtok(NULL,":"));

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/STS",mac);

    //填充报文
    memcpy(buf,dMac,6);
    buf[6] = device_type;
    buf[7] = time1;
    buf[8] = time2;
    buf[9] = time3;
    buf[10] = time4;
    sendData.payload = buf;
    sendData.payloadlen = 11;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送开关时间段设置指令,结果:%d,网关:%s,节点:%s,设备类型:%d,合闸时间: %02d:%02d,拉闸时间: %02d:%02d \n",ret,mac,subMac,device_type,time1,time2,time3,time4);
    
    return ret;
}

//多个开关时间段设置,新增20201228
int SendOnOffTimeMuilt(char* mac,char* subMac,MYSQL *_db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int device_type = 0;
    char switch_time1[10] = {0};
    char switch_time2[10] = {0};
    char switch_time3[10] = {0};
    char switch_time4[10] = {0};
    int time1 = 0;
    int time2 = 0;
    int time3 = 0;
    int time4 = 0;
    int time5 = 0;
    int time6 = 0;
    int time7 = 0;
    int time8 = 0;
    int swith_action1 = 0;
    int swith_action2 = 0;
    int swith_action3 = 0;
    int swith_action4 = 0;
    int t1 = 0;
    int t2 = 0;
    int t3 = 0;
    int t4 = 0;
    int time_count = 2;
    char buf[256] = {0};
    unsigned char dMac[30] = {0};

    //判断网关 子节点
    if(strcmp(subMac,"") == 0) //网关
    {
        sprintf(query,"select device_type,swith_time1,swith_time2,swith_time3,swith_time4,swith_action1,swith_action2,swith_action3,swith_action4 "
                    "from dev_info_gateway where device_mac ='%s'",mac);
        HexStrToByte("0F0000000001",dMac,12);
    }
    else
    {
        sprintf(query,"select device_type,swith_time1,swith_time2,swith_time3,swith_time4,swith_action1,swith_action2,swith_action3,swith_action4 "
                      "from dev_info_node where device_mac ='%s'",subMac);
        HexStrToByte(subMac,dMac,12);
    }
    
    //数据库查询
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    //优化 新增对查询字段长度的判断 20210930 chw
    if(!row[0] || !row[1] || !row[2] || !row[5] || !row[6] || strlen(row[1])!=5 || strlen(row[2])!=5 || strlen(row[5])!=1 || strlen(row[6])!=1)
    {
        log("%s,%s 设备类型,第一组时间点、开关动作字段为空 \n",mac,subMac);
        mysql_free_result(res);
        return 1;
    }

    strcpy(switch_time1,row[1]);
    strcpy(switch_time2,row[2]);
    swith_action1 = atoi(row[5]);
    swith_action2 = atoi(row[6]);
    time1 = atoi(strtok(switch_time1,":"));
    time2 = atoi(strtok(NULL,":"));
    time3 = atoi(strtok(switch_time2,":"));
    time4 = atoi(strtok(NULL,":"));
    sendData.payloadlen = 14;

    //处理时间前大后小问题 20230525
    if(time1 > time3 || (time1 == time3 && time2 > time4))
    {
        t1 = time1;
        t2 = time2;
        t3 = time3;
        t4 = time4;
        time1 = t3;
        time2 = t4;
        time3 = t1;
        time4 = t2;
        swith_action1 = 0;
        swith_action2 = 1;
    }

    //优化 新增对查询字段长度的判断 20210930 chw
    if(!row[3] || !row[4] || !row[7] || !row[8] || strlen(row[3])!=5 || strlen(row[4])!=5 || strlen(row[7])!=1 || strlen(row[8])!=1)
    {
        log("%s,%s 设备类型,第二组时间点、开关动作字段为空,只发送第一组 \n",mac,subMac);
    }
    else
    {
        time_count = 4;
        sendData.payloadlen = 20;
        strcpy(switch_time3,row[3]);
        strcpy(switch_time4,row[4]);
        swith_action3 = atoi(row[7]);
        swith_action4 = atoi(row[8]);
        time5 = atoi(strtok(switch_time3,":"));
        time6 = atoi(strtok(NULL,":"));
        time7 = atoi(strtok(switch_time4,":"));
        time8 = atoi(strtok(NULL,":"));

        buf[14] = time5;
        buf[15] = time6;
        buf[16] = swith_action3;
        buf[17] = time7;
        buf[18] = time8;
        buf[19] = swith_action4;
    }
    

    if (strcmp(subMac,"") == 0) //网关
    {
        device_type = 2;
    }
    else
    {
        device_type = atoi(row[0]);
    }
    mysql_free_result(res);
    

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/STS",mac);

    //填充报文
    memcpy(buf,dMac,6);
    buf[6] = device_type;
    buf[7] = time_count;
    buf[8] = time1;
    buf[9] = time2;
    buf[10] = swith_action1;
    buf[11] = time3;
    buf[12] = time4;
    buf[13] = swith_action2;
    
    sendData.payload = buf;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送开关时间段设置指令,结果:%d,网关:%s,节点:%s,设备类型:%d,时间点一:%02d:%02d,时间二:%02d:%02d,时间点三:%02d:%02d,时间点四:%02d:%02d,动作1:%d,动作2:%d,动作3:%d,动作4:%d \n",
        ret,mac,subMac,device_type,time1,time2,time3,time4,time5,time6,time7,time8,swith_action1,swith_action2,swith_action3,swith_action4);
    
    return ret;
}


//获取子节点版本号
int SendGetSubVersion(char* mac,char* subMac)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    char topicName[256];
    char buf[256] = {0};
    unsigned char nodeMac[30] = {0};

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/GNV",mac);

    //填充报文
    if(strcmp(subMac,"") == 0)
    {
        HexStrToByte("0F0000000001",nodeMac,12);
    }
    else
    {
        HexStrToByte(subMac,nodeMac,12);
    }
    memcpy(buf,nodeMac,6);
    sendData.payload = buf;
    sendData.payloadlen = 6;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送获取子节点版本号指令,结果:%d,网关:%s,节点:%s \n",ret,mac,subMac);

    return ret;
}


//开关控制模式设置从数据库info表
int SendSwitchModeFromDB(char* mac,char* subMac,MYSQL* _db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int device_type = 0;
    int control_mode = 0;
    char buf[256] = {0};
    unsigned char dMac[30] = {0};

    //判断网关 子节点
    if(strcmp(subMac,"") == 0) //网关
    {
        sprintf(query,"select device_type,control_mode from dev_info_gateway where device_mac ='%s'",mac);
        HexStrToByte("0F0000000001",dMac,12);
    }
    else
    {
        sprintf(query,"select device_type,control_mode from dev_info_node where device_mac ='%s'",subMac);
        HexStrToByte(subMac,dMac,12);
    }
    
    //数据库查询
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1])
    {
        log("%s device_type,control_mode 为空",dMac);
        mysql_free_result(res);
        return 1;
    }

    if (strcmp(subMac,"") == 0) //网关
    {
        device_type = 2;
    }
    else
    {
        device_type = atoi(row[0]);
    }
    control_mode = atoi(row[1]);
    mysql_free_result(res);

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/SCM",mac);

    //填充报文
    memcpy(buf,dMac,6);
    buf[6] = device_type;
    buf[7] = control_mode;
    sendData.payload = buf;
    sendData.payloadlen = 8;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送开关控制模式指令,结果:%d,网关:%s,节点:%s,节点类型:%d,控制模式:%d \n",ret,mac,subMac,device_type,control_mode);
    
    return ret;
}

//调光节点分组设置
int SendDimmingNodeGroup(char* mac,char* subMac,MYSQL* _db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int device_type = 0;
    int device_group = 0;
    char time_seg1[10] = {0};
    char time_seg2[10] = {0};
    char time_seg3[10] = {0};
    char time_seg4[10] = {0};
    int time1[2] = {0};
    int time2[2] = {0};
    int time3[2] = {0};
    int time4[2] = {0};
    int dimming_seg1 = 0;
    int dimming_seg2 = 0;
    int dimming_seg3 = 0;
    int dimming_seg4 = 0;
    int dimming_mode = 0;
    int dimming_type = 0;
    char buf[256] = {0};
    unsigned char nodeMac[30] = {0};


    sprintf(query,"select device_type,device_group,time_seg1,time_seg2,time_seg3,time_seg4,dimming_seg1,dimming_seg2,dimming_seg3,dimming_seg4,"
                  "dimming_mode,dimming_type from dev_info_node where device_mac ='%s'",subMac);

    
    //数据库查询
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        log("%s 调光节点分组 NULL == res \n",subMac);
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        log("%s 调光节点分组 NULL == row \n",subMac);
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7] || !row[8] || !row[9] || !row[10] || !row[11])
    {
        log("%s 调光节点分组有字段设置为空! \n",subMac);
        mysql_free_result(res);
        return 1;
    }

    if(strlen(row[0]) == 0 || strlen(row[1]) == 0 || strlen(row[2]) == 0 || strlen(row[3]) == 0 || strlen(row[4]) == 0 \
        || strlen(row[5]) == 0 || strlen(row[6]) == 0 || strlen(row[7]) == 0 || strlen(row[8]) == 0 || strlen(row[9]) == 0 || strlen(row[10]) == 0 || strlen(row[11]) == 0)
    {
        log("%s 调光节点分组有时间设置为空白! \n",subMac);
        mysql_free_result(res);
        return 1;
    }
    device_type = atoi(row[0]);
    device_group = atoi(row[1]);
    strcpy(time_seg1,row[2]);
    strcpy(time_seg2,row[3]);
    strcpy(time_seg3,row[4]);
    strcpy(time_seg4,row[5]);
    dimming_seg1 = atoi(row[6]);
    dimming_seg2 = atoi(row[7]);
    dimming_seg3 = atoi(row[8]);
    dimming_seg4 = atoi(row[9]);
    dimming_mode = atoi(row[10]);
    dimming_type = atoi(row[11]);
    mysql_free_result(res);
    time1[0] = atoi(strtok(time_seg1,":"));
    time1[1] = atoi(strtok(NULL,":"));
    time2[0] = atoi(strtok(time_seg2,":"));
    time2[1] = atoi(strtok(NULL,":"));
    time3[0] = atoi(strtok(time_seg3,":"));
    time3[1] = atoi(strtok(NULL,":"));
    time4[0] = atoi(strtok(time_seg4,":"));
    time4[1] = atoi(strtok(NULL,":"));

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/DGS",mac);

    //填充报文
    HexStrToByte(subMac,nodeMac,12);
    memcpy(buf,nodeMac,6);
    buf[6] = device_type;
    buf[7] = device_group;
    buf[8] = time1[0];
    buf[9] = time1[1];
    buf[10] = dimming_seg1;
    buf[11] = time2[0];
    buf[12] = time2[1];
    buf[13] = dimming_seg2;
    buf[14] = time3[0];
    buf[15] = time3[1];
    buf[16] = dimming_seg3;
    buf[17] = time4[0];
    buf[18] = time4[1];
    buf[19] = dimming_seg4;
    buf[20] = dimming_mode;
    buf[21] = dimming_type;
    sendData.payload = buf;
    sendData.payloadlen = 22;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送调光节点分组设置指令,结果:%d,网关:%s,节点:%s,节点类型:%d,组号:%d,时间1: %02d:%02d,时间2: %02d:%02d,时间3: %02d:%02d,时间4: %02d:%02d,亮度1:%d,,亮度2:%d,"
          "亮度3:%d,亮度4:%d,调光模式:%d,调光类型:%d \n",ret,mac,subMac,device_type,device_group,time1[0],time1[1],time2[0],time2[1],time3[0],time3[1],
          time4[0],time4[1],dimming_seg1,dimming_seg2,dimming_seg3,dimming_seg4,dimming_mode,dimming_type);
    usleep(500000);
    return ret;
}

//调光节点分组数据修改
int SendDimmingNodeGroupModify(char* mac,int group,MYSQL* _db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer; 
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    int device_group = 0;
    char time_seg1[10] = {0};
    char time_seg2[10] = {0};
    char time_seg3[10] = {0};
    char time_seg4[10] = {0};
    int time1[2] = {0};
    int time2[2] = {0};
    int time3[2] = {0};
    int time4[2] = {0};
    int dimming_seg1 = 0;
    int dimming_seg2 = 0;
    int dimming_seg3 = 0;
    int dimming_seg4 = 0;
    int dimming_mode = 0;
    int dimming_type = 0;
    char buf[256] = {0};


    sprintf(query,"select device_group,time_seg1,time_seg2,time_seg3,time_seg4,dimming_seg1,dimming_seg2,dimming_seg3,dimming_seg4,"
                  "dimming_mode,dimming_type from dev_dimming_group where gateway_mac ='%s' and device_group = %d",mac,group);

    
    //数据库查询
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        log("%s 调光节点分组记录为空! \n",mac);
        mysql_free_result(res);
        return 1;
    }
    
    if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7] || !row[8] || !row[9] || !row[10])
    {
        log("%s 调光节点分组有节点为空! \n",mac);
        mysql_free_result(res);
        return 1;
    }
    device_group = atoi(row[0]);
    strcpy(time_seg1,row[1]);
    strcpy(time_seg2,row[2]);
    strcpy(time_seg3,row[3]);
    strcpy(time_seg4,row[4]);
    dimming_seg1 = atoi(row[5]);
    dimming_seg2 = atoi(row[6]);
    dimming_seg3 = atoi(row[7]);
    dimming_seg4 = atoi(row[8]);
    dimming_mode = atoi(row[9]);
    dimming_type = atoi(row[10]);
    mysql_free_result(res);
    time1[0] = atoi(strtok(time_seg1,":"));
    time1[1] = atoi(strtok(NULL,":"));
    time2[0] = atoi(strtok(time_seg2,":"));
    time2[1] = atoi(strtok(NULL,":"));
    time3[0] = atoi(strtok(time_seg3,":"));
    time3[1] = atoi(strtok(NULL,":"));
    time4[0] = atoi(strtok(time_seg4,":"));
    time4[1] = atoi(strtok(NULL,":"));

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/DGM",mac);

    //填充报文
    buf[0] = device_group;
    buf[1] = time1[0];
    buf[2] = time1[1];
    buf[3] = dimming_seg1;
    buf[4] = time2[0];
    buf[5] = time2[1];
    buf[6] = dimming_seg2;
    buf[7] = time3[0];
    buf[8] = time3[1];
    buf[9] = dimming_seg3;
    buf[10] = time4[0];
    buf[11] = time4[1];
    buf[12] = dimming_seg4;
    buf[13] = dimming_mode;
    buf[14] = dimming_type;
    sendData.payload = buf;
    sendData.payloadlen = 15;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    log(" ↓发送调光节点分组数据修改指令,结果:%d,网关:%s,组号:%d,时间1: %02d:%02d,时间2: %02d:%02d,时间3: %02d:%02d,时间4: %02d:%02d,亮度1:%d,,亮度2:%d,"
          "亮度3:%d,亮度4:%d,调光模式:%d,调光类型:%d \n",ret,mac,device_group,time1[0],time1[1],time2[0],time2[1],
          time3[0],time3[1],time4[0],time4[1],dimming_seg1,dimming_seg2,dimming_seg3,dimming_seg4,dimming_mode,dimming_type);
    
    return ret;
}

//传感器报警阈值设置
int SendSensorThreshold(char* mac,MYSQL* _db)
{
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    MYSQL_RES* res = NULL;
    MYSQL_ROW row;
    char query[1024] = {0};
    char topicName[256];
    char buf[256] = {0};
    int temperature_min = 0;
    int temperature_max = 100;
    int humidity_min = 0;
    int humidity_max = 100;
    double x_offset_max = 5.0;
    double y_offset_max = 5.0;
    double z_offset_max = 5.0;
    int line_temperature_max = 100;
    int step = 0;
    char sendPrint[256] = {0};
    char vlog[512] = {0};

    sprintf(query,"select temperature_min,temperature_max,humidity_min,humidity_max,x_offset_max,y_offset_max,z_offset_max,line_temperature_max "
            "from dev_info_gateway where device_mac = '%s'",mac);
    excuteSql(_db,query);
    res = mysql_store_result(_db);
    if (NULL == res)
    {
        return 1;
    }
    row = mysql_fetch_row(res);
    if (NULL == row)
    {
        mysql_free_result(res);
        return 1;
    }

    //读取到温湿度配置
    if(row[0] && row[1] && row [2] && row [3])
    {
        temperature_min = atoi(row[0]);
        temperature_max = atoi(row[1]);
        humidity_min = atoi(row[2]);
        humidity_max = atoi(row[3]);
        buf[step] = 1;
        buf[step+1] = temperature_min;
        buf[step+2] = temperature_max;
        buf[step+3] = humidity_min;
        buf[step+4] = humidity_max;
        step += 5;

        sprintf(vlog,"%s温度最小值:%d,温度最大值:%d,湿度最小值:%d,湿度最大值:%d;",vlog,temperature_min,temperature_max,humidity_min,humidity_max);
    }

    //读取陀螺仪配置
    if(row[4] && row[5] && row [6])
    {
        x_offset_max = atof(row[4]);
        y_offset_max = atof(row[5]);
        z_offset_max = atof(row[6]);
        int x_offset_max_i = (int)(x_offset_max*10);
        int y_offset_max_i = (int)(y_offset_max*10);
        int z_offset_max_i = (int)(z_offset_max*10);
        buf[step] = 2;
        buf[step+1] = ((char*)&x_offset_max_i)[1];
        buf[step+2] = ((char*)&x_offset_max_i)[0];
        buf[step+3] = ((char*)&y_offset_max_i)[1];
        buf[step+4] = ((char*)&y_offset_max_i)[0];
        buf[step+5] = ((char*)&z_offset_max_i)[1];
        buf[step+6] = ((char*)&z_offset_max_i)[0];
        step += 7;

        sprintf(vlog,"%sx倾斜角最大值:%f,y倾斜角最大值:%f,z倾斜角最大值:%f;",vlog,x_offset_max,y_offset_max,z_offset_max);
    }

    //读取线温阈值配置
    if(row[7])
    {
        buf[step] = 4;
        line_temperature_max = atoi(row[7]);
        buf[step+1] = line_temperature_max;
        step += 2;

        sprintf(vlog,"%s线温最大值:%d;",vlog,line_temperature_max);
    }

    mysql_free_result(res);

    if(strlen(vlog) == 0)
    {
        log("数据库没有读取到传感器阈值!网关:%s",mac);
        return 1;
    }

    //主题
    if(strcmp(mac,"") == 0)
    {
        return 1;
    }
    sprintf(topicName,"PP/%s/CFG/SAT",mac);

    //填充报文
    sendData.payload = buf;
    sendData.payloadlen = step;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName, &sendData);
    Hex2Str(buf,sendPrint,sendData.payloadlen);
    log(" ↓发送传感器阈值指令,结果:%d,网关:%s,sendPrint:%s,%s \n",ret,mac,sendPrint,vlog);
    return ret;
}


//电表节点分组设置
//int ()