#include "kk_data_mng.h"
#include "kk_lan_vp_ctrl.h"
#include "kk_lan_debug.h"
#include "cJSON.h"
#include "kk_voice_panel_cfg.h"
#include "kk_lan_sync.h"
#ifdef VOICE_SUPPORT
typedef cJSON *(*dev_handle_func)(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);

typedef struct {
	const int *pidAry;
	int num;
	dev_handle_func func;
}DEV_PID_S;

static cJSON *air_conditioner_dev_handle(const char *deviceCode,int ep,uint8_t *arg,uint8_t arg_len);

static cJSON *light_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *curtain_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *outlet_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *freshAir_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *fanCoilSwitch_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *underfloor_heating_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);
static cJSON *dimming_light_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node);

static const int air_conditioner_dev_pid[] = AIR_CONDITIONER_DEV_PID;

static const int light_dev_pid[] = LIGHT_DEV_PID;
static const int curtain_dev_pid[] = CURTAIN_DEV_PID;
static const int outlet_dev_pid[] = OUTLET_DEV_PID;
static const int freshAir_dev_pid[] = FRESHAIR_DEV_PID;
static const int fanCoilSwitch_dev_pid[] = FANCOILSWITCH_DEV_PID;
static const int underfloor_heating_dev_pid[] = UNDERFLOOR_HEATING_DEV_PID;
static const int dimming_light_dev_pid[] = DIMMING_LIGHT_DEV_PID;





static DEV_PID_S g_dev_pid[] = {
	{ light_dev_pid,sizeof(light_dev_pid)/ sizeof(int),light_dev_handle},
	{ curtain_dev_pid,sizeof(curtain_dev_pid) / sizeof(int),curtain_dev_handle},
	{ outlet_dev_pid,sizeof(outlet_dev_pid) / sizeof(int),outlet_dev_handle},
	{ freshAir_dev_pid,sizeof(freshAir_dev_pid) / sizeof(int),freshAir_dev_handle},
	{ fanCoilSwitch_dev_pid,sizeof(fanCoilSwitch_dev_pid) / sizeof(int),fanCoilSwitch_dev_handle},
	{ underfloor_heating_dev_pid,sizeof(underfloor_heating_dev_pid) / sizeof(int),underfloor_heating_dev_handle},
	{ dimming_light_dev_pid,sizeof(dimming_light_dev_pid) / sizeof(int),dimming_light_dev_handle},
};
	
static dev_handle_func dev_pid_dispatch(int pid)
{
	int i,j;
	int num = sizeof(g_dev_pid) / sizeof(DEV_PID_S);
	DEV_PID_S *pDevPid = g_dev_pid;
	
	for (i = 0; i<num ; i++,pDevPid++) {
		for (j = 0; j < pDevPid->num;j++) {
			if(pid==pDevPid->pidAry[j]){
				return pDevPid->func;
			}
		}
	}

	return NULL;
}


static cJSON *get_value(kk_map_dev_node_t *node,const char* key)
{
	cJSON *value = NULL;
	int i,size;

	if(key==NULL||node==NULL||node->newccu==NULL||node->newccu->type!=cJSON_Array){
		return NULL;
	}

	size = cJSON_GetArraySize(node->newccu);

	for(i=0;i<size;i++){
		cJSON *obj = cJSON_GetArrayItem(node->newccu,i);
		cJSON *id = cJSON_GetObjectItem(obj,"identifier");
		if(id==NULL){
			continue;
		}
		if(strcmp(id->valuestring,key)==0){
			value =  cJSON_GetObjectItem(obj,"value");
			return value;
		}
	}
	
	return NULL;
}






//****************************************************************************
cJSON *air_conditioner_dev_powerswitch_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}

static cJSON *air_conditioner_dev_windspeed_msg_build(int ep,int level)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WindSpeed",level);

	return params;
}

static cJSON *air_conditioner_dev_workmode_msg_build(int ep,int mode)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WorkMode",mode);

	return params;
}
static cJSON *air_conditioner_dev_temperature_msg_build(int ep,int tmp)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"Temperature",tmp);

	return params;
}


static cJSON *air_conditioner_dev_handle(const char *deviceCode,int ep,uint8_t *arg,uint8_t arg_len)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;
	
	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param =air_conditioner_dev_powerswitch_msg_build(ep,1);
		}break;
			
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param =air_conditioner_dev_powerswitch_msg_build(ep,0);
		}break;

		case VP_CTRL_WINDSPEE_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			
			uint8_t windspeed = arg[2];
			debug_log(LOG_INFO_LEVEL,"[windspeed] %d\n",windspeed);

			if(windspeed==VP_SKILLTYPE_12_WINDSPEED_LOW){
				param = air_conditioner_dev_windspeed_msg_build(ep,2);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_MID){
				param = air_conditioner_dev_windspeed_msg_build(ep,3);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_HIGH){
				param = air_conditioner_dev_windspeed_msg_build(ep,4);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_AUTO){
				param = air_conditioner_dev_windspeed_msg_build(ep,0);
			}
		}break;

		case VP_CTRL_MODE:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t mode = arg[2];
			debug_log(LOG_INFO_LEVEL,"[mode] %d\n",mode);
			
			if(mode==VP_SKILLTYPE_1C_WORKMODE_COLD){
				param = air_conditioner_dev_workmode_msg_build(ep,1);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_HEATING){
				param = air_conditioner_dev_workmode_msg_build(ep,2);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_FAN){
				param = air_conditioner_dev_workmode_msg_build(ep,3);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_DEHUM){
				param = air_conditioner_dev_workmode_msg_build(ep,4);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_AUTO){
				param = air_conditioner_dev_workmode_msg_build(ep,0);
			}
		}break;
		
		case VP_CTRL_TMP_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t tmp = arg[2];
			debug_log(LOG_INFO_LEVEL,"[tmp] %d\n",tmp);
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			param = air_conditioner_dev_temperature_msg_build(ep,tmp);
		}break;

		case VP_CTRL_WINDSPEE_UP:{
			if(arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			INDOOR_AIR_STATUS * pStatus = indoor_airstatus_table_find_item(deviceCode,ep);
		
			if(pStatus==NULL){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			if(pStatus->online!=1){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] offline\n");
				return NULL;
			}
						
			debug_log(LOG_INFO_LEVEL,"[pStatus->WindSpeed] %d\n",pStatus->WindSpeed);
			debug_log(LOG_INFO_LEVEL,"[WindSpeed] inc\n");

			if(pStatus->WindSpeed==2){
				param = air_conditioner_dev_windspeed_msg_build(ep,3);
			}else if(pStatus->WindSpeed==3||pStatus->WindSpeed==4||pStatus->WindSpeed==0){
				param = air_conditioner_dev_windspeed_msg_build(ep,4);
			}

		}break;

		case VP_CTRL_WINDSPEE_DOWN:{
			if(arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
		
			INDOOR_AIR_STATUS * pStatus = indoor_airstatus_table_find_item(deviceCode,ep);
		
			if(pStatus==NULL){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}
			
			if(pStatus->online!=1){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] offline\n");
				return NULL;
			}

			
			debug_log(LOG_INFO_LEVEL,"[pStatus->WindSpeed] %d\n",pStatus->WindSpeed);
			debug_log(LOG_INFO_LEVEL,"[WindSpeed] dec\n");
			
			if(pStatus->WindSpeed==4){
				param = air_conditioner_dev_windspeed_msg_build(ep,3);
			}else if(pStatus->WindSpeed==3||pStatus->WindSpeed==2||pStatus->WindSpeed==0){
				param = air_conditioner_dev_windspeed_msg_build(ep,2);
			}
		}break;

		case VP_CTRL_TMP_UP:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			INDOOR_AIR_STATUS * pStatus = indoor_airstatus_table_find_item(deviceCode,ep);
		
			if(pStatus==NULL){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			if(pStatus->online!=1){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] offline\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[pStatus->Temperature] %f\n",pStatus->Temperature);
			debug_log(LOG_INFO_LEVEL,"[tmp] inc %d\n",arg[3]);
			double tmp = pStatus->Temperature + arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			debug_log(LOG_INFO_LEVEL,"[tmp] %f\n",tmp);
			param = air_conditioner_dev_temperature_msg_build(ep,tmp);	
		}break;
	
		case VP_CTRL_TMP_DOWN:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			
			INDOOR_AIR_STATUS * pStatus = indoor_airstatus_table_find_item(deviceCode,ep);
		
			if(pStatus==NULL){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			if(pStatus->online!=1){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] offline\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[pStatus->Temperature] %f\n",pStatus->Temperature);
			debug_log(LOG_INFO_LEVEL,"[tmp] dec %d\n",arg[3]);

			double tmp = pStatus->Temperature - arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			debug_log(LOG_INFO_LEVEL,"[tmp] %f\n",tmp);
			param = air_conditioner_dev_temperature_msg_build(ep,tmp);	
			
		}break;

		default:break;
	}
	return param;
}


static cJSON *light_dev_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}

static cJSON *light_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;

	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = light_dev_msg_build(ep,1);
		}break;
			
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = light_dev_msg_build(ep,0);
		}break;

		default:break;
	}
	return param;
}




static cJSON *curtain_dev_mode_msg_build(int ep,int OperationMode)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"OperationMode",OperationMode);

	return params;
}

static cJSON *curtain_dev_position_msg_build(int ep,int position)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"OperationMode",1);
	cJSON_AddNumberToObject(params,"Position",position);
	

	return params;
}


static cJSON *curtain_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;

	switch(skill_type){
		case VP_CTRL_OPEN:{
			if(arg_len==3&&arg[1]==0x20){
				int position = arg[2];
				debug_log(LOG_INFO_LEVEL,"[position] %d%\n",position);
				if(position<0){
					position = 0;
				}else if(position>100){
					position = 100;
				}
				param = curtain_dev_position_msg_build(ep,position);
			}else{
				debug_log(LOG_INFO_LEVEL,"[mode] open\n");
				param = curtain_dev_mode_msg_build(ep,1);
			}
		}break;
			
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[mode] close\n");
			param = curtain_dev_mode_msg_build(ep,0);
		}break;

		case VP_CTRL_STOP:{
			debug_log(LOG_INFO_LEVEL,"[mode] stop\n");
			param = curtain_dev_mode_msg_build(ep,2);
		}
		default:break;
	}
	return param;
}


static cJSON *outlet_dev_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}



static cJSON *outlet_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;

	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = outlet_dev_msg_build(ep,1);
		}break;
			
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = outlet_dev_msg_build(ep,0);
		}break;
		default:break;
	}
	return param;
}



cJSON *freshair_dev_powerswitch_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}


static cJSON *freshair_dev_windspeed_msg_build(int ep,int level)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WindSpeed",level);

	return params;
}

static cJSON *freshair_dev_workmode_msg_build(int ep,int mode)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WorkMode",mode);

	return params;
}



static cJSON *freshAir_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;
	
	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = freshair_dev_powerswitch_msg_build(ep,1);
		}break;

		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = freshair_dev_powerswitch_msg_build(ep,0);
		}break;

		case VP_CTRL_WINDSPEE_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t windspeed = arg[2];
			debug_log(LOG_INFO_LEVEL,"[windspeed] %d\n",windspeed);

			if(windspeed==VP_SKILLTYPE_12_WINDSPEED_LOW){
				param = freshair_dev_windspeed_msg_build(ep,1);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_MID){
				param = freshair_dev_windspeed_msg_build(ep,2);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_HIGH){
				param = freshair_dev_windspeed_msg_build(ep,3);
			}
		}break;
			
		case VP_CTRL_MODE:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t mode = arg[2];
			debug_log(LOG_INFO_LEVEL,"[mode] %d\n",mode);

			if(mode==VP_SKILLTYPE_1C_WORKMODE_AUTO){
				param = freshair_dev_workmode_msg_build(ep,0);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_MANUAL){
				param = freshair_dev_workmode_msg_build(ep,1);
			}
		}break;
			
		case VP_CTRL_WINDSPEE_UP:{
			if(arg_len!=3||arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}


			cJSON *value = get_value(node,"WindSpeed");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			if(value->valueint==0){
				param = freshair_dev_windspeed_msg_build(ep,1);
			}else if(value->valueint==1){
				param = freshair_dev_windspeed_msg_build(ep,2);
			}else if(value->valueint==2||value->valueint==3){
				param = freshair_dev_windspeed_msg_build(ep,3);
			}

		}break;

		case VP_CTRL_WINDSPEE_DOWN:{
			if(arg_len!=3||arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
		
			cJSON *value = get_value(node,"WindSpeed");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			if(value->valueint==3){
				param = freshair_dev_windspeed_msg_build(ep,2);
			}else if(value->valueint==2){
				param = freshair_dev_windspeed_msg_build(ep,1);
			}else if(value->valueint==1||value->valueint==0){
				param = freshair_dev_windspeed_msg_build(ep,0);
			}
		}break;

		

		default:break;
	}
	return param;
}

cJSON *fanCoilSwitch_powerswitch_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}


static cJSON *fancoilswitch_dev_windspeed_msg_build(int ep,int level)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WindSpeed",level);

	return params;
}
static cJSON *fancoilswitch_dev_workmode_msg_build(int ep,int mode)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WorkMode",mode);

	return params;
}

static cJSON *fanCoilSwitch_Temperature_msg_build(int ep,int tmp)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"Temperature",tmp);

	return params;
}

static cJSON *fanCoilSwitch_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;

	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = fanCoilSwitch_powerswitch_msg_build(ep,1);
		}break;

		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = fanCoilSwitch_powerswitch_msg_build(ep,0);
		}break;

		case VP_CTRL_WINDSPEE_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t windspeed = arg[2];
			debug_log(LOG_INFO_LEVEL,"[windSpeed] %d\n",windspeed);
			if(windspeed==VP_SKILLTYPE_12_WINDSPEED_LOW){
				param = fancoilswitch_dev_windspeed_msg_build(ep,2);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_MID){
				param = fancoilswitch_dev_windspeed_msg_build(ep,3);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_HIGH){
				param = fancoilswitch_dev_windspeed_msg_build(ep,4);
			}else if(windspeed==VP_SKILLTYPE_12_WINDSPEED_AUTO){
				param = fancoilswitch_dev_windspeed_msg_build(ep,0);
			}else{
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
		}break;
		
		case VP_CTRL_MODE:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t mode = arg[2];
			debug_log(LOG_INFO_LEVEL,"[mode] %d\n",mode);
			if(mode==VP_SKILLTYPE_1C_WORKMODE_COLD){
				param = fancoilswitch_dev_workmode_msg_build(ep,1);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_HEATING){
				param = fancoilswitch_dev_workmode_msg_build(ep,2);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_FAN){
				param = fancoilswitch_dev_workmode_msg_build(ep,3);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_DEHUM){
				param = fancoilswitch_dev_workmode_msg_build(ep,4);
			}else{
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
		}break;
		
		case VP_CTRL_TMP_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t tmp = arg[2];
			debug_log(LOG_INFO_LEVEL,"[tmp] %d\n",tmp);
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			
			param = fanCoilSwitch_Temperature_msg_build(ep,tmp);
		}break;
			

		case VP_CTRL_WINDSPEE_UP:{
			if(arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			cJSON *value = get_value(node,"WindSpeed");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[WindSpeed] inc\n");

			if(value->valueint==2){
				param = fancoilswitch_dev_windspeed_msg_build(ep,3);
			}else if(value->valueint==3){
				param = fancoilswitch_dev_windspeed_msg_build(ep,4);
			}else if(value->valueint==4||value->valueint==0){
				param = fancoilswitch_dev_windspeed_msg_build(ep,4);
			}else{
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value=%d\n",value->valueint);
				return NULL;
			}
		}break;

		case VP_CTRL_WINDSPEE_DOWN:{
			if(arg[1]!=0x42){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
		
			cJSON *value = get_value(node,"WindSpeed");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[WindSpeed] dec\n");

			if(value->valueint==4){
				param = fancoilswitch_dev_windspeed_msg_build(ep,3);
			}else if(value->valueint==3){
				param = fancoilswitch_dev_windspeed_msg_build(ep,2);
			}else if(value->valueint==2||value->valueint==0){
				param = fancoilswitch_dev_windspeed_msg_build(ep,2);
			}else{
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value=%d\n",value->valueint);
				return NULL;
			}
		}break;

		case VP_CTRL_TMP_UP:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			cJSON *value = get_value(node,"Temperature");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}
			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[tmp] inc %d\n",arg[3]);
			double tmp = value->valuedouble + arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			debug_log(LOG_INFO_LEVEL,"[tmp] %f\n",tmp);
			param = fanCoilSwitch_Temperature_msg_build(ep,tmp);	
		}break;
	
		case VP_CTRL_TMP_DOWN:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			
			cJSON *value = get_value(node,"Temperature");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[tmp] dec %d\n",arg[3]);

			double tmp = value->valuedouble - arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<17){
				tmp = 17;
			}
			debug_log(LOG_INFO_LEVEL,"[tmp] %f\n",tmp);
			param = fanCoilSwitch_Temperature_msg_build(ep,tmp);	
			
		}break;

		default:break;
	}

	
	return param;
}



cJSON *underfloor_heating_powerswitch_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}

static cJSON *underfloor_heating_workmode_msg_build(int ep,int mode)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WorkMode",mode);
	

	return params;
}
static cJSON *underfloor_heating_temperature_msg_build(int ep,int tmp)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"WorkMode",1);
	cJSON_AddNumberToObject(params,"Temperature",tmp);

	return params;
}




static cJSON *underfloor_heating_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;
	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = underfloor_heating_powerswitch_msg_build(ep,1);
		}break;
			
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = underfloor_heating_powerswitch_msg_build(ep,0);
		}break;

		case VP_CTRL_MODE:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t mode = arg[2];
			debug_log(LOG_INFO_LEVEL,"[mode] %d\n",mode);
			if(mode==VP_SKILLTYPE_1C_WORKMODE_AUTO){
				param = underfloor_heating_workmode_msg_build(ep,0);
			}else if(mode==VP_SKILLTYPE_1C_WORKMODE_MANUAL){
				param = underfloor_heating_workmode_msg_build(ep,1);
			}
		}break;
		
		case VP_CTRL_TMP_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t tmp = arg[2];
			debug_log(LOG_INFO_LEVEL,"[tmp] %d\n",tmp);
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<20){
				tmp = 20;
			}
			param = underfloor_heating_temperature_msg_build(ep,tmp);
		}break;
			

		case VP_CTRL_TMP_UP:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			cJSON *value = get_value(node,"Temperature");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}
			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[tmp] inc %d\n",arg[3]);

			double tmp = value->valuedouble + arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<20){
				tmp = 20;
			}
			debug_log(LOG_INFO_LEVEL,"tmp=%f\n",tmp);
			param = underfloor_heating_temperature_msg_build(ep,tmp);	
		}break;
		
		case VP_CTRL_TMP_DOWN:{
			if(arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			
			
			cJSON *value = get_value(node,"Temperature");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}
			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[tmp] dec %d\n",arg[3]);

			double tmp = value->valuedouble - arg[3];
			
			if(tmp>30){
				tmp = 30;
			}else if(tmp<20){
				tmp = 20;
			}
			debug_log(LOG_INFO_LEVEL,"tmp=%f\n",tmp);
			param = underfloor_heating_temperature_msg_build(ep,tmp);
		}break;

		default:break;
	}
	return param;
}

cJSON *dimming_light_dev_powerSwitch_msg_build(int ep,int onoff)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);
	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",onoff);
	return params;
}

static cJSON *dimming_light_dev_colortemperature_msg_build(int ep,int val)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"ColorTemperature",val);

	return params;
}
static cJSON *dimming_light_dev_brightness_msg_build(int ep,int val)
{
	char epNum[12] = {0};
	cJSON *params = cJSON_CreateObject();

	memset(epNum,0,sizeof(epNum));
	snprintf(epNum,sizeof(epNum),"%d",ep);

	cJSON_AddStringToObject(params,"epNum",epNum);
	cJSON_AddNumberToObject(params,"PowerSwitch",1);
	cJSON_AddNumberToObject(params,"Brightness",val);

	return params;
}

static cJSON *dimming_light_dev_handle(int ep,uint8_t *arg,uint8_t arg_len,kk_map_dev_node_t *node)
{
	uint8_t skill_type = arg[0];
	cJSON *param = NULL;
	
	switch(skill_type){
		case VP_CTRL_OPEN:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] on\n");
			param = dimming_light_dev_powerSwitch_msg_build(ep,1);
		}break;
		
		case VP_CTRL_CLOSE:{
			debug_log(LOG_INFO_LEVEL,"[OnOff] off\n");
			param = dimming_light_dev_powerSwitch_msg_build(ep,0);
		}break;
		
		case VP_CTRL_SET_COLOR_TMP:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t mode = arg[2];
			debug_log(LOG_INFO_LEVEL,"[mode] %d\n",mode);
			if(mode==0x01){
				param = dimming_light_dev_colortemperature_msg_build(ep,20);
			}else if(mode==0x02){
				param = dimming_light_dev_colortemperature_msg_build(ep,50);
			}else if(mode==0x03){
				param = dimming_light_dev_colortemperature_msg_build(ep,100);
			}
		}break;
		
		case VP_CTRL_BRIGHTNESS_SET:{
			if(arg_len!=3||arg[1]!=0x20){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}
			uint8_t bri = arg[2];
			debug_log(LOG_INFO_LEVEL,"[bri] %d\n",bri);
			if(bri>100){
				bri = 100;
			}else if(bri<=1){
				bri = 1;
			}
			param = dimming_light_dev_brightness_msg_build(ep,bri);
		}break;
			

		case VP_CTRL_BRIGHTNESS_DOWN:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}

			cJSON *value = get_value(node,"Brightness");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[bri] dec %d\n",arg[3]);

			int bri = value->valueint-arg[3];
			if(bri>100){
				bri = 100;
			}else if(bri<=1){
				bri = 1;
			}
			debug_log(LOG_INFO_LEVEL,"bri=%d\n",bri);

			param = dimming_light_dev_brightness_msg_build(ep,bri);
		}break;

		case VP_CTRL_BRIGHTNESS_UP:{
			if(arg_len!=5||arg[1]!=0x42&&arg[2]!=0x02){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] para err\n");
				return NULL;
			}


			cJSON *value = get_value(node,"Brightness");
			if(value==NULL||value->type!=cJSON_Number){
				debug_log(LOG_WARNING_LEVEL,"[ctrl fail] value err\n");
				return NULL;
			}

			debug_log(LOG_INFO_LEVEL,"[value] %d\n",value->valueint);
			debug_log(LOG_INFO_LEVEL,"[bri] inc %d\n",arg[3]);
			
			int bri = value->valueint+arg[3];
			if(bri>100){
				bri = 100;
			}else if(bri<=1){
				bri = 1;
			}
			debug_log(LOG_INFO_LEVEL,"bri=%d\n",bri);

			param = dimming_light_dev_brightness_msg_build(ep,bri);
		}break;
			
		default:break;
	}
	return param;
}


int kk_lan_vp_control(uint8_t num,uint32_t nodeIdAry[],uint8_t *arg,uint8_t arg_len)
{
	uint8_t i,j;
	int err = 1;
	uint8_t skill_type;
	int ep;
	int pid = 0;
	dev_handle_func func;

	char productCode[PRODUCT_CODE_LEN] = {0};
	char deviceCode[DEVICE_CODE_LEN] = {0};
	

	cJSON *msg = NULL;
	cJSON *params = NULL;
	
	kk_map_dev_node_t *node = NULL;

	if(arg_len<=1){
		debug_log(LOG_ERROR_LEVEL,"[err].\n");
		return 1;
	}
	skill_type = arg[0];


	for(i=0;i<num;i++){
		memset(deviceCode,0,sizeof(deviceCode));
		memset(productCode,0,sizeof(productCode));
		kk_lan_db_deviceCode_get(nodeIdAry[i],deviceCode);
		kk_lan_db_channel_get(nodeIdAry[i],&ep);

		if(kk_map_dev_search_by_deviceCode(deviceCode,&node) != 0){
			continue ;
		}
		
		snprintf(productCode,sizeof(productCode),"%s",node->productCode);


		pid = atoi(productCode);

		params = NULL;

		if(is_ac_gw_pid(pid)!=0){
			params = air_conditioner_dev_handle(deviceCode,ep,arg,arg_len);
		}else{
			if((func = dev_pid_dispatch(pid))!=NULL){
				
				if(node==NULL){
					debug_log(LOG_WARNING_LEVEL,"[ctrl fail] node=NULL\n");
					continue ;
				}
				
				if(node->online_status==0){
					debug_log(LOG_WARNING_LEVEL,"[ctrl fail] dev offline\n");
					continue ;
				}
				
				params = func(ep,arg,arg_len,node);
			}
		}
		
		if(params!=NULL){
			msg=property_set(productCode,deviceCode,"*","*",params);
			kk_ipc_send_json(msg);
			err = 0;
		}
	}


	return err;
}
#endif





















