/************************************************************
*版权所有 （C）2020，公司（或个人）名称
*
*文件名称： kk_sub_db.c
*内容摘要： 网关设备和子设备设备表处理模块
*其他说明： 
*当前版本：  
*************************************************************/

#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_sub_db.h"
#include "kk_property_db.h"
#include "kk_dm_mng.h"
#include "kk_dm_msg.h"
#include "kk_scene_handle.h"
#include "kk_dm_heartbeat.h"
#include "kk_dm_api.h"
#include "sqlite3.h"
#include "kk_log.h"
#include "kk_hal.h"
extern sqlite3 *g_kk_pDb;

typedef struct {
	void *mutex;
	int  subDevNum;
	sqlite3 *pDb;	
} kk_subDb_ctx_t;


static kk_subDb_ctx_t s_kk_subDb_ctx = {NULL,0,NULL};
static kk_subDb_ctx_t *_kk_subDb_get_ctx(void)
{
	return &s_kk_subDb_ctx;
}
static void _kk_subDb_lock(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	if (ctx->mutex) {
		HAL_MutexLock(ctx->mutex);
	}
}

static void _kk_subDb_unlock(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	if (ctx->mutex) {
		HAL_MutexUnlock(ctx->mutex);
	}
}

/************************************************************
*功能描述：设备表的初始化
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

static int kk_subDev_db_Init(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//eUtils_LockLock(&sLock);
	_kk_subDb_lock();
	
	ctx->pDb = g_kk_pDb;

	INFO_PRINT("sub db Database opened\n");
	{
		const char *pSubDevTable = "CREATE TABLE IF NOT EXISTS SubDeviceInfo( \
			idx INTEGER, \
			isOffline INTEGER, \
			productCode varchar(33), \
			deviceCode varchar(33) UNIQUE, \
			mac varchar(17), \
			fatherDeviceCode varchar(33), \
			version varchar(33), \
			isAuth INTEGER, \
			devType INTEGER, \
			heartbeat INTEGER,\
			productType varchar(33),\
			sceneSupport INTEGER)";

		char *pcErr;

//     DBG_vPrintf(DBG_SQL, "Execute SQL: '%s'\n", pConditionTableDef);

		if (sqlite3_exec(ctx->pDb, pSubDevTable, NULL, NULL, &pcErr) != SQLITE_OK)
		{
			ERROR_PRINT("Error creating table (%s)\n", pcErr);
			sqlite3_free(pcErr);
			//eUtils_LockUnlock(&sLock);
			_kk_subDb_unlock();
			return FAIL_RETURN;
		}
	}

	//eUtils_LockUnlock(&sLock);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：开机从设备数据库导出数据到内存
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
static int _kk_load_subDevice(void)
{
	const char *searchCmd = "select * from SubDeviceInfo;";	
	sqlite3_stmt *stmt;	
	int deviceType = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	int devId = 0,heartbeat = 0;
	int res = 0;
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		deviceType = sqlite3_column_int(stmt, DB_SUB_DEVTYPE);
		res = dm_mgr_subdev_create(deviceType,
	   					(char*)sqlite3_column_text(stmt, DB_SUB_PRODUCTCODE),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_MAC),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_FATHERDEVICECODE),
	   					KK_DEV_UNKNOW,&devId,&heartbeat);
	
		if(res != SUCCESS_RETURN){
			ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__);
		}
		else{
			ctx->subDevNum++;
		}
		usleep(100000);
		// send the topo info
		//iotx_dm_subscribe(devId);

	   //sync the data from property db
	   kk_property_sync_values((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   usleep(100000);

	   if(deviceType == KK_DM_DEVICE_GATEWAY){
			kk_dm_gw_status_check_push((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   }
	   //post the property to cloud
	   //dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE));
	    //kk_dm_ota_report_version(devId,sqlite3_column_text(stmt, DB_VERSION));//post version
	   //usleep(100000);
    }	
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;

}
/************************************************************
*功能描述：设备数据模块初始化
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDb_init(void)
{
	int res = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	
	/* Create Mutex */
	ctx->mutex = HAL_MutexCreate();
	if (ctx->mutex == NULL) {
		return FAIL_RETURN;
	}

	res = kk_subDev_db_Init();
	if(res != SUCCESS_RETURN){
		ERROR_PRINT("[%s][%d]kk_wlist_db_Init FAIL!!!\n",__FUNCTION__,__LINE__);

	}
	_kk_load_subDevice();
	//kk_load_subDevice();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：检查设备是否有重复
*输入参数：deviceCode：设备deviceCode
*输出参数：无
*返 回 值：1:存在；0：不存在
*其他说明：
*************************************************************/

static int _kk_check_subDev_exist(const char* deviceCode)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *pmac = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo;";	
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   pmac = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
	   if(!strcmp(deviceCode,pmac))
	   
{
		 isExist = 1;
		 break;
	   }
    }
    INFO_PRINT("\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return isExist;

}

/************************************************************
*功能描述：保存设备信息到数据库
*输入参数：devType：设备类型
          productCode：产品Id
          deviceCode:设备deviceCode
          fatherDeviceCode:上一级网关的deviceCode
          mac: mac地址
          version：版本号
          heartbeat：心跳时间

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_insert_db(int devType,char productCode[PRODUCT_CODE_MAXLEN], \
										char deviceCode[DEVICE_CODE_MAXLEN],char fatherDeviceCode[DEVICE_CODE_MAXLEN],char mac[DEVICE_MAC_MAXLEN],char version[DEVICE_VERSION_MAXLEN],int heartbeat)
{
	const char *insertCmd = "insert into SubDeviceInfo (idx,isOffline,productCode,deviceCode,mac,fatherDeviceCode,version,isAuth,devType,heartbeat,sceneSupport) \
								values ('%d','%d', '%s','%s','%s','%s','%s','%d','%d','%d','%d');";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();


	if(_kk_check_subDev_exist((const char*)deviceCode) == 1)
	{
		WARNING_PRINT("[%s][%d] DATA ALREADY EXIST!!!\n",__FUNCTION__,__LINE__);
		return SUCCESS_RETURN;
	}
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(insertCmd,ctx->subDevNum,0,productCode,deviceCode,mac,fatherDeviceCode,version,0,devType,heartbeat,0);	

	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	ctx->subDevNum++;
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
										
/************************************************************
*功能描述：删除设备信息
*输入参数：deviceCode:设备deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN])
{
	const char *deleteCmd = "delete from SubDeviceInfo where deviceCode = '%s';";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(deleteCmd,deviceCode);	

	INFO_PRINT("Table delete data sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("Table delete data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新是否在线信息
*输入参数：deviceCode:设备deviceCode
          isOffline：1，离线；0，在线
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_update_offline(int isOffline,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isOffline=%d  WHERE deviceCode= '%s'",isOffline,deviceCode);	
	INFO_PRINT("kk_subDev_update_offline sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	//_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新设备类型
*输入参数：deviceCode:设备deviceCode
          productType：设备类型
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_update_productType(char *productType,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET productType='%s'  WHERE deviceCode= '%s'",productType,deviceCode);	
	INFO_PRINT("kk_subDev_update_productType sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("Table updata data successfully\n");
	}
    sqlite3_free(sqlCmd);
	//_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新设备注册标记
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_update_auth(int isAuth,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isAuth=%d  WHERE deviceCode= '%s'",isAuth,deviceCode);	
	INFO_PRINT("kk_subDev_update_auth sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   INFO_PRINT("Table updata data successfully\n");
	}
    sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：更新设备注册标记
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_check_auth(int devType)
{
	char *sqlCmd = NULL;
	sqlite3_stmt *stmt;	
	int rc = 0;
	char *zErrMsg = 0;
	const char *searchCmd = "select * from SubDeviceInfo WHERE devType = '%d';";	
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	printf("------------------------------------------------------->111\n");
	sqlCmd = sqlite3_mprintf(searchCmd,devType);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);		
	while(sqlite3_step(stmt) == SQLITE_ROW){
		printf("------------------------------------------------------->222\n");
	    char *pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
	   	char *pProductCode = (char*)sqlite3_column_text(stmt, DB_SUB_PRODUCTCODE);
		kk_msg_cloud_status_notify(pProductCode,pDeviceCode);
		//kk_subDev_update_auth(1,pDeviceCode);
    }
	sqlite3_finalize(stmt);
    sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：更新内场景支持，此接口只针对网关设备有效
*输入参数：deviceCode:设备deviceCode
          sceneSupport：1，支持内场景；0，不支持
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_update_sceneSupport(int sceneSupport,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET sceneSupport=%d  WHERE deviceCode= '%s'",sceneSupport,deviceCode);	
	INFO_PRINT("kk_subDev_update_sceneSupport sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}


/************************************************************
*功能描述：主机重新上线后向云端上报属性
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_send_property_get_from_db(void)
{
	const char *searchCmd = "select * from SubDeviceInfo;";	
	sqlite3_stmt *stmt;	
	int isOffline = 0;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	int res = 0;
	dm_mgr_dev_node_t *node = NULL;	
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   isOffline = sqlite3_column_int(stmt, DB_SUB_DEVTYPE);
	   if(isOffline == KK_DEV_ONLINE){
		   res = dm_mgr_get_device_by_devicecode((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE), &node);
		   if (res != SUCCESS_RETURN) {
		       continue;
		   }
		   iotx_dm_dev_online(node->devid);

		   dm_msg_thing_property_post_all((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   }
    }	
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;


}
/************************************************************
*功能描述：主机断电重启后向网关获取所有子设备属性
*输入参数：fatherDeviceCode：网关deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_send_property_get(const char *fatherDeviceCode)
{
	int res = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;		
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE fatherDeviceCode = '%s'";	

	if(fatherDeviceCode == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}
	sqlCmd = sqlite3_mprintf(searchCmd,fatherDeviceCode);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		res = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		if (res != SUCCESS_RETURN) {
			ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
			continue;
		}
		/*休眠设备，不需要下发获取属性*/
		if(node->dormancyDev){
			continue;
		}
		/*发送之前先置为KK_DEV_UNKNOW*/
		node->isOffline = KK_DEV_UNKNOW;
		kk_msg_execute_property_get(node);
		usleep(100000);
	}

	sqlite3_finalize(stmt);
	sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;


}

/************************************************************
*功能描述：检查网关是否支持内场景
*输入参数：deviceCode：网关deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_check_scene_support(const char *deviceCode)
{
	int res = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE devType= '%d' and sceneSupport = '%d'";	

	if(deviceCode == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}

	sqlCmd = sqlite3_mprintf(searchCmd,KK_DM_DEVICE_GATEWAY,1);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		if (!strcmp(deviceCode,pDeviceCode)) {
			res = 1;
		}
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sqlCmd);
	return res;
}

/************************************************************
*功能描述：向所有同类设备执行动作，场景设置中用到
*输入参数：productType：设备类型
          sceneId：场景Id
          propertyName:属性名
          propertyValue：属性值
          type：执行类型
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
typedef struct{
	char *type;
	char *maptype;
}productype_map_s;
static productype_map_s producTypeMap[] = {
	{"CURTAIN","curtain"},
	{"WINDOW","actuator"},	
	{"LIGHT","switch"},		
	{"LIGHT_STRIP","colorDimmableLight"},	
	{"LIGHT_DIMMER","lightPanel"},		
	{"SOCKET","outlet"},	
	{"AC_IndoorUnit","air"},	
	{"FLOOR_HEATING","floorHeating"},	
	{"FRESH_AIR","airConditioning"},	
	{"AIR_SWITCH","airSwitch"},	
};
int kk_get_product_type_table_size(void)
{
	return sizeof(producTypeMap)/sizeof(productype_map_s);
}
int kk_subDev_set_action_by_productType(const char *productType,const char *sceneId,const char *propertyName,const char *propertyValue,const char *type,int delay)
{
	int res = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE productType= '%s'";	
	int idx = 0;
	int gw_support_scene = 0;
	kk_tsl_data_t *property = NULL;
	int k = 0,count  = 0;
	char typeArray[10][32] = {0};
	int size = 0;
	char *pStart = NULL;

	if(productType == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}
	INFO_PRINT("kk_subDev_set_action_by_productType called!!!\n");
	size = kk_get_product_type_table_size();
	//printf("---------------------------->size:%d\n",size);
	for(k = 0; k < size; k++){
		//printf("---------------------------->producTypeMap[k].type:%s\n",producTypeMap[k].type);
		if(!strcmp(productType,producTypeMap[k].type)){
			memcpy(typeArray[count],producTypeMap[k].maptype,strlen(producTypeMap[k].maptype));
			//printf("---------------------------->producTypeMap[k].maptype:%s\n",producTypeMap[k].maptype);
			count++;
			if(count >= 10){
				break;
			}
		}
	}
	for(k = 0; k < count; k++){
		//printf("---------------------------->typeArray[k]:%s\n",typeArray[k]);
		sqlCmd = sqlite3_mprintf(searchCmd,typeArray[k]);	//curtain type
		sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
		//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
		while(sqlite3_step(stmt) == SQLITE_ROW){
		   pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		   res = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		   if (res != SUCCESS_RETURN) {
			   continue;
		   }
		   if(kk_subDev_check_scene_support(node->fatherDeviceCode) == 1){
				gw_support_scene = 1;
		   }	
		   else{
				gw_support_scene = 0;
		   }
		   //if(!strcmp(typeArray[k],"switch")){
			for(idx = 0; idx < node->dev_shadow->property_number; idx++){
				property = (kk_tsl_data_t *)(node->dev_shadow->properties + idx);
				if(property == NULL){
					continue;
				}	
				if(strstr(property->identifier,propertyName) != NULL){
					if(gw_support_scene){
						kk_scene_action_detail_t info = {0};
						memcpy(info.deviceCode,node->deviceCode,strlen(node->deviceCode));
						memcpy(info.propertyName,property->identifier,strlen(property->identifier));
						memcpy(info.propertyValue,propertyValue,strlen(propertyValue));
						//printf("------------------->property->identifier:%s\n",property->identifier);
						pStart = strstr(property->identifier,"_");
						if(pStart != NULL){
							//printf("------------------->num:%s\n",pStart+1);
							info.epNum = atoi(pStart+1);
						}else{
							info.epNum = 1;
						}
						info.delay = delay;
						kk_scene_action_add(node->fatherDeviceCode,sceneId,info);
						res = kk_scene_insert_scene_action(type,node->deviceCode,info.epNum,
								property->identifier,propertyValue,info.delay,sceneId,node->fatherDeviceCode);
						if(res != SUCCESS_RETURN){
							INFO_PRINT("kk_subDev_set_action_by_productType fail!!!\n");
							//return res;
							continue;
						}						
					}
					
				}
			}

		   //}
#if 0		   
		   else{
			   if(gw_support_scene){
				   kk_scene_action_detail_t info = {0};
				   memcpy(info.deviceCode,node->deviceCode,strlen(node->deviceCode));
				   memcpy(info.propertyName,propertyName,strlen(propertyName));
				   memcpy(info.propertyValue,propertyValue,strlen(propertyValue));
				   info.epNum = 1;
				   info.delay = 0;
				   kk_scene_action_add(node->fatherDeviceCode,sceneId,info);
			   }
			   res = kk_scene_insert_scene_action(type,node->deviceCode,1,
					   propertyName,propertyValue,0,sceneId,node->fatherDeviceCode);
			   if(res != SUCCESS_RETURN){
				   INFO_PRINT("kk_subDev_set_action_by_productType fail!!!\n");
				   //return res;
				   continue;
			   }	   
		   }
#endif		   
	    }
		sqlite3_finalize(stmt);
		sqlite3_free(sqlCmd);		
	}
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新设备注册标记
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_getSensors_reply(SensorType_t*list)
{
	char *sqlCmd = NULL;
	int rc = 0;
	const char *searchCmd = "select * from SubDeviceInfo WHERE productType= '%s'";
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;	
	int currentValue = 0;
	int count = 0;
	//printf("kk_subDev_getSensors_reply----------------------start\n");
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,"sensor");
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		//printf("kk_subDev_getSensors_reply----------------------num\n");
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		rc = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		if (rc != SUCCESS_RETURN) {
			ERROR_PRINT("ERROR res:%d\n",rc);
			continue;
		}
		//printf("pDeviceCode:%s\n",pDeviceCode);
		kk_property_db_get_value(pDeviceCode,"SensorType",&currentValue);
		//printf("currentValue:%d\n",currentValue);
		memcpy(list[count].deviceCode,pDeviceCode,strlen(pDeviceCode));
		list[count].SensorType = currentValue;
		count++;
	}
	//printf("kk_subDev_getSensors_reply----------------------end\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;
}



