/*
 * MQ_CCU_Adapter.cpp
 *
 *  Created on: Dec 6, 2018
 *      Author: sds
 */
#include "MQ_CCU_Adapter.h"
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include "json/writer.h"
#include "json/reader.h"
#include "json/value.h"
#include "ace/Reactor.h"

#include "KK_Util.h"
#include "EH_Client.h"

#include "MQ_CCU_Config.h"
// #include "kk_connect.h"
#include "LSC_Logger.h"
#include "EH_ToolKit.h"
#include "EH_Exception.h"
// #include "KK_CcuConfig.h"
#include "KK_OTA.h"
#include "kk_PTPO.h"


#define CCU_REQ_TIMEOUT 3


//下面这部分代码是什么意思？
MQ_CCU_Adapter* MQ_CCU_Adapter::ms_pInstance = NULL;

MQ_CCU_Adapter* MQ_CCU_Adapter::GetInstance() {
	if (ms_pInstance == NULL) {
		ms_pInstance = new MQ_CCU_Adapter();
	}
	return ms_pInstance;
}

MQ_CCU_Adapter::MQ_CCU_Adapter():cond(mtx) {
//	int reqSize = MQ_CCU_Config::GetInstance()->getReqCacheSize(); //获取请求缓存大小
//	m_pReqInfo = new REQ_MAP(reqSize,NULL);
//	m_pReqTimeoutInfo = new REQTIMEOUT_MAP(reqSize,NULL);
//	timoutTimerArgs = new TIMOUTTIMERARGS_MAP(reqSize,NULL);

	ccuStatus = "UNINIT";
	mqttSdk = KK_MQTTSDK::GetInstance();	//KK_MQTTSDK接口初始化
	mqttSdk->setSdkCallbackHandler(this);	//设置Sdk回调处理程序

	this->msg_queue()->low_water_mark(600*1024);
	this->msg_queue()->high_water_mark(600*1024);
}
int MQ_CCU_Adapter::svc(){
	for (ACE_Message_Block* msg_blk; getq(msg_blk) != -1;) {
		LOGI("KK_IotHandler rec a msg.\n");

		try {
			EH::Json::Reader reader;
			EH::Json::Value json_root;
			string json = string(msg_blk->rd_ptr());
			if (!reader.parse(json, json_root) || !json_root.isObject()) {
				LOGW("Parse json error. json is:%s\n", json.c_str());
			   msg_blk->release();
			   continue;
			}
			string opcode = json_root["opcode"].asString();
			string nodeid = json_root["nodeid"].asString();
			string arg = json_root["arg"].asString();
			string requester = json_root["requester"].asString();

			unsigned long nowReqTime = getSystemTimeInMs();
			if( (nowReqTime - lastCcuReqTime) > 100){
				client->sendRequest(nodeid,opcode,arg,requester);
				lastCcuReqTime = nowReqTime;
			}else{
				LOGW("send req to ccu too fast,wait 100ms.\n");
				usleep(200*1000);
				client->sendRequest(nodeid,opcode,arg,requester);
				lastCcuReqTime = getSystemTimeInMs();
			}
		} catch (exception &e) {
			LOGW("%s.\n", e.what());
		}
		msg_blk->release();
	}
	return 0;
}
void MQ_CCU_Adapter::sendReqToCcu(string opcode,string nodeid,string arg,string requester){
	LOGD("sendReqToCcu opcode:%s,nodeid:%s,arg:%s,requester:%s.\n",opcode.c_str(),nodeid.c_str(),arg.c_str(),requester.c_str());
	ACE_Time_Value timeout(0, 300 * 1000);
	EH::Json::Value json;
	json["opcode"] = opcode;
	json["nodeid"] = nodeid;
	json["arg"] = arg;
	json["requester"] = requester;
	string wholeMsg = json.toStyledString();
	ACE_Message_Block* blk = new ACE_Message_Block(wholeMsg.length() + 1);
	blk->copy(wholeMsg.c_str());
	int ret = Put(blk,&timeout);
	if (ret <= 0) {
		printf("Send msg to IotHandler failed.msg is %s\n",wholeMsg.c_str());
		blk->release();
	}
}
int MQ_CCU_Adapter::Put(ACE_Message_Block* mblk, ACE_Time_Value* relativeTimeout) {
	ACE_Time_Value* absTimeout = NULL;
	if (relativeTimeout != NULL) {
		absTimeout = new ACE_Time_Value(ACE_OS::gettimeofday() + *relativeTimeout);
	}
	int ret = putq(mblk, absTimeout);
	if (absTimeout != NULL) {
		delete absTimeout;
	}

	return ret;
}
int MQ_CCU_Adapter::open() {
	int ret = activate(THR_DETACHED, 1);
	if(ret == -1){
		LOGW("Init KK_IotHandler failed.\n");
	}
	ccuId = MQ_CCU_Config::GetInstance()->getCcuId(); //获取主机ID
	gw_id = EH_ToolKit::GetMacNoSpace();
	if(ccuId == ""){
		LOGE("cannot find ccuid,is a konke ccu machine ???");
		return -1;
	}
	LOGI("start mqtt for ccu:%s \n",ccuId.c_str());

	//房间信息
	string roomid = KK_HwDevManager::GetInstance()->GetRoomId();
	roomidok = KK_HwDevManager::GetInstance()->loadroomid(onlyroomid); //是否创建了房间标志。1 创建 0 未创建
	LOGI("roomid ok: %d  roomid %s ",roomidok,roomid.c_str());
	if(roomidok == -1){
		SaveRoomEnable = true;
		LOGW("未创建房间，等待创建.\n");
	}else{
		LOGI("Roma特定房间不可删 roomid %s ",roomid.c_str());
	}

	//客户端初始化
	client = new EH_Client();
	client->init("", "", this, false);

	//开启TCP 与UDP
	// kk_connect::GetInstance()->init( KK_HwDevManager::GetInstance()->getCcuId(), "",false);

	//连接Roma平台，绑定就进行启动
	oninitmqttsdk();
	//升级检测
	kk_PTPO::GetInstance()->init(gw_id);
	return 0;
}

//---ccu communication 主机通信
//客户端状态更改时
void MQ_CCU_Adapter::onClientStatusChanged(EH_Client::ClientStatus currentStatus) {
	LOGI("ccu client status:%s \n",EH_Client::getClientStatusStr(currentStatus).c_str());

	if (currentStatus == EH_Client::WORKING) {
		handleNewDevices = true;
		ccuSyncOK = true;
		string arg = "{\"conditions\":[{\"condition_type\":\"dev_list\",\"condition_arg\":[]}]}";
		client->sendRequest("*", "GET_ZIGBEE_DEVS_HW_INFO", arg, "HJ_Config");

		if(roomidok == -1){
			LOGW("未创建房间，开始创建.\n");
			sleep(1);
			addCCuroom();
		}
	}else{
		ccuSyncOK = false;
		handleNewDevices = false;
	}
}

//接收处理中控发来的消息
void MQ_CCU_Adapter::onRecvMsg(string nodeId, string opcode, EH::Json::Value arg, string status){   //接受中控向上推送的报文。
	try {
	LOGD("Konkexinghai recv MQ_CCU_AdapterMsg:\n   nodeId:%s\n   status:%s\n   opcode:%s \n   arg:%s.\n",nodeId.c_str(),status.c_str(),opcode.c_str(),EH_ToolKit::JsonToString(arg).c_str());
	if (opcode == "SYNC_INFO") {
//		if(!ccuSyncOK){
			handleSyncInfo(arg,opcode);
			ccuSyncOK = false;
//		}
	}if (opcode == "SYNC_INFO_PUSH" ) {
			handleSyncInfo(arg,opcode);
	}  else if (opcode == "NEW_DEVICES") {
		newDevices = arg["new_devices"];
		newCentralAcDevices = arg["new_central_ac_indoorunits"];
		newCentralAcGwsDevices = arg["new_central_ac_gws"];
		if(handleNewDevices){
			handleNewDevice(newDevices, newCentralAcDevices, newCentralAcGwsDevices);
			handleNewDevices = false;
			LOGI("sync ccu finish,upload %d devices status to hw cloud.\n",hwSubDevs.size());
		}
	}else if (opcode == "GET_CCU_INFO") {
		handlegwNodeId(arg);
	} else if (opcode == "NEW_DEVICES_NOTIFY") {
		handleNewDevice(newDevices, newCentralAcDevices, newCentralAcGwsDevices);
		newDevices = "";
		newCentralAcDevices = "";
		newCentralAcGwsDevices = "";
	} else if (opcode == "ZIGBEE_DEV_JOIN_NOTIFY"){ //Zigbee 设备入网推送
		handle_Dev_Join_Notify(arg);
	}  else if (opcode == "GET_ZIGBEE_DEVS_HW_INFO"){
		if(ccuSyncOK){
			loadAllSubDev(arg);
			client->sendRequest("*", "SYNC_INFO", "*", "HJ_Config");
		}else{
			handleGetDevsHardwareInfo(arg);
		}
	} else if (opcode == "ZIGBEE_DEV_HW_INFO_PUSH"){
		handleDevOnlinePush(arg);
	} else if (opcode == "SWITCH"  || opcode == "SETUP_NODE"||opcode == "SHORTCUT_PANEL_ACTIVE"
			||opcode == "FRESH_AIR_RUN_MODEL"||opcode == "FRESH_AIR_SWITCH"||opcode == "FRESH_AIR_SPEED_SET"||opcode == "FRESH_AIR_SET_FILTER_SCREEN_TIME"
			||opcode == "FRESH_AIR_CONFIG_ARGS_PUSH"||opcode == "FRESH_AIR_GET_CONFIG_ARGS"||opcode == "CHOPIN_FRESH_AIR_STATUS"||opcode == "FRESH_AIR_SET_LOCK_STATUS"
			||opcode == "SENSOR_BOOL"||opcode == "POWER_NOTIFY"||opcode == "SENSOR_BOOL_STATUS"||opcode == "SOS_STATUS"||opcode == "ZIGBEE_ALERTOR_STATUS"
			||opcode == "ADJUST_LUMINANCE" ||opcode == "GET_DIMMABLE_LIGHT_CONFIG"||opcode == "SET_DIMMABLE_LIGHT_CONFIG"||opcode == "DIMMABLE_LIGHT_STATUS"  //调光灯
			||opcode == "SET_WORK_TEMPERATURE"||opcode == "FAN_COIL_CONFIG_ARGS_PUSH"
			||opcode == "SET_WORK_MODEL"||opcode == "FLOOR_HEATING_GET_CONFIG_ARGS"||opcode == "FLOOR_HEATING_SET_LOCK_STATUS" ||opcode == "FLOOR_HEATING_DEV_STATUS" 
			||opcode == "FAN_COIL_SET_RUN_MODEL"||opcode == "FAN_COIL_SET_FUN_SPEED"||opcode == "FAN_COIL_SET_LOCK_STATUS"||opcode == "FAN_COIL_GET_CONFIG_ARGS"
			||opcode == "FAN_COIL_SET_DELAY_SWITCH_TASK"||opcode == "FAN_COIL_SET_TEMPERATURE"||opcode == "FAN_COIL_STATUS" 
			) {  //opcode == "NIGHT_MODE" 小夜灯
		//更改设备状态信息
		kk_handleDeviceInfo::GetInstance()->handleDeviceStatusChanged(hwSubDevs,nodeId2channelMap,nodeId,opcode,arg,pushTopic,gw_id);
	} else if(opcode == "ADD_INSTALL_CODE" && status == "success"){
		sleep(1);
		if(gw_NodeId == nodeId){
			client->sendRequest(gw_NodeId, "OPEN_NET_CHANNEL", "*", "HJ_Server");
			}else{
				LOGW("未有Z3网关，主机不支持使用.\n");
			}
	}else if (opcode == "ADD_ROOM") { //添加特定房间
		saveCCuroom(arg);
	} else if (opcode == "DEL_DEV") { //小K删除设备同步到华为，给其推送离线。DEL_DEV
		loadDelete(arg);
	} else if (opcode == "OPEN_NET_CHANNEL"&& status == "success") { //打开组网
		KKdiscover =true;//
		LOGD("OPEN_NET_CHANNEL  discoveryEnable:%d,KKdiscover:%d\n",discoveryEnable,this->KKdiscover);
	} else if (opcode == "CLOSE_NET_CHANNEL"&& status == "success") { //关闭组网
		KKdiscover =false;//
	} else if (opcode == "CENTRAL_AC_INDOOR_UNIT_STATUS"||opcode == "CENTRAL_AC_INDOOR_UNIT_SETTING") { //中央空调内机
		// kk_handleDeviceInfo::GetInstance()->handleCentralACStatusPush(hwSubDevs,indoorunitsId2AddrMap,pushTopic,nodeId, arg,opcode);
	}

	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
}

//接收云端下发的消息
void MQ_CCU_Adapter::onCloudMsgRecv(string payload,string topicName){
	try{
		LOGI("onCloudMsgRecv is: %s  topicName: %s\n",payload.c_str(),topicName.c_str());

		EH::Json::Value jsonObject;
		EH::Json::Reader reader;
		if (!reader.parse(payload, jsonObject) || !jsonObject.isObject()) {
			LOGW("Message format is wrong.primary msg is: %s\n",payload.c_str());
			return;
		}

		vector<string> chanMac;
		Split(topicName,"/",chanMac);
		string Sub_Topic = chanMac[3];

		if(Sub_Topic == "devices_public"){     		//功能Topic 13. 获取设备列表信息
			kk_handleDeviceInfo::GetInstance()->onGetDevService(hwSubDevs,controllerModel,pushTopic);
		}else if(Sub_Topic == "device"){ //子设备
			if(chanMac[4] == "delete"){ 	 		//功能Topic 3. 删除子设备
				string sn = jsonObject["mac"].asString();
				onDeviceRequestDelete(sn);
			}else if(chanMac[4] == "search"){   	//功能Topic 2. 搜索子设备
				on_Query_GateWay_Infomation();
				onDeviceRequestJoin(true);
			}else if(chanMac[4] == "stopsearch"){   //功能Topic 20. 停止搜索子设备
				onDeviceRequestJoin(false);
			}else if(chanMac[4] == "set"){   	 	//功能Topic 6. 改变子设备状态
				string sn = jsonObject["mac"].asString();
				EH::Json::Value   cmd = jsonObject["datapoints"];
				kk_handleDeviceInfo::GetInstance()->onSetDevService(hwSubDevs,sn,cmd); //下发控制命令
			}
		}else if(Sub_Topic == "cg_custom_msg"){ 	//功能Topic 16. XCG发送自定义数据到PTP
		}else if(Sub_Topic == "firmware"){ 			//功能Topic 18. 查询最新的升级任务结果  "/firmware/check/result";
			kk_PTPO::GetInstance()->handle_check_result(payload); 
		}else if(Sub_Topic == "switch"){ 	 		//运维Topic 21. 网关地址切换
		}else if(Sub_Topic == "optcall"){ 	 		//运维Topic 25. 运维功能调用
			kk_PTPO::GetInstance()->handle_Ptpo_optcall(payload,pushTopic);
		}else if(Sub_Topic == "gwevent"){ 	 		//运维Topic 27. 网关事件通知
		}else{
			LOGW("recv unknown Topic:%s.\n",Sub_Topic.c_str());
		}
	} catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
}

//下发查询网关信息
int MQ_CCU_Adapter::on_Query_GateWay_Infomation(){
	client->sendRequest("*", "GET_CCU_INFO", "*", "HJ_Server");
}

//发送设备控制命令
int MQ_CCU_Adapter::send_Control_Info(string wholeMsg){
	ACE_Time_Value timeout(0, 300 * 1000);
	ACE_Message_Block* blk = new ACE_Message_Block(wholeMsg.length() + 1);
	blk->copy(wholeMsg.c_str());
	int ret = Put(blk,&timeout);
	if (ret <= 0) {
		LOGW("Send msg to IotHandler failed.msg is %s\n",wholeMsg.c_str());
		blk->release();
		return -1;
	}
	return 0;
}

int MQ_CCU_Adapter::addCCuroom(){
	EH::Json::Value roomarg;
	roomarg["name"] = "Roma特定房间不可删";
	roomarg["room_icon"] = "a_0";
	roomarg["floor_id"] = "3";
	roomarg["room_pos"] = "10";
	string arg = EH_ToolKit::JsonToString(roomarg);
		client->sendRequest("*","ADD_ROOM",arg,"HJ_Config");
	return 0;
}
int MQ_CCU_Adapter::saveCCuroom(EH::Json::Value arg){
	LOGD("prepare  add room\n");
	string ccuroomid = IntToString(arg.asInt());
	if(SaveRoomEnable){
	KK_HwDevManager::KKRoomId roominfo;
	roominfo.roonid = ccuroomid;
	roominfo.name = "Roma特定房间不可删";
	onlyroomid[ccuroomid] = roominfo;
	LOGD("prepare  add room \n");
	KK_HwDevManager::GetInstance()->saveroomid(onlyroomid);
	SaveRoomEnable = false;
	roomidok = 1;
	}
	return 0;
}

//检测特定房间，是否存在与否。
void MQ_CCU_Adapter::Specific_rooms(EH::Json::Value rooms) {
	int roomCount = rooms.size();
	map<string,string>  roomMap;
	for (int i = 0; i < roomCount; i++) {
		EH::Json::Value room = rooms[i];
		string roomID = room["id"].asString();
		roomMap[roomID] = roomID;
	}
	string roomid = KK_HwDevManager::GetInstance()->GetRoomId();//特定的房间
	map<string,string>::iterator it = roomMap.find(roomid);
	if(it == roomMap.end()){
		LOGW("Roma特定的房间被删除，开始重新创建，小K重新进入才会显示.\n");
		onlyroomid.erase(roomid);
		SaveRoomEnable = true;
		addCCuroom();
	}
}

int MQ_CCU_Adapter::onDeviceRequestJoin(bool enableJoinSubdev){
	LOGD("onDeviceRequestJoin enableJoinSubdev:%s\n",enableJoinSubdev?"true":"false");
	this->discoveryEnable = enableJoinSubdev;
	if(discoveryEnable){
		if(gw_NodeId!= "-1"){
//			string arg = "{\"type\":1,\"mac\":\""+mac+"\",\"code\":\""+code+"\"}";
//			client->sendRequest(gw_NodeId, "ADD_INSTALL_CODE", arg, "HJ_Server"); //Pin码组网
			client->sendRequest(gw_NodeId, "OPEN_NET_CHANNEL", "*", "HJ_Server");
		}else{
			LOGW("未有Z3网关，主机不支持使用.\n");
		}
	}else{
		if(gw_NodeId!= "-1"){
			client->sendRequest(gw_NodeId, "CLOSE_NET_CHANNEL", "*", "HJ_Server");
		}else{
			LOGW("未有Z3网关，主机不支持使用.\n");
		}
	}
	return 0;
}

void MQ_CCU_Adapter::handleGetDevsHardwareInfo(EH::Json::Value arg){
	if(arg.isArray()){
		for(int i = 0;i < arg.size();i++){
			handleDevOnlinePush(arg[i]);
		}
	}
}

//子设备的在线离线
void MQ_CCU_Adapter::handleDevOnlinePush(EH::Json::Value arg){
	try {
	string respTopic_1 = pushTopic +"/device/sync";//子设备在线
	string sn = Replace(arg["mac"].asString(),":","");
	map<string, kk_handleDeviceInfo::HwSubDev*>::iterator subDevIt = hwSubDevs.find(sn);
	if(subDevIt != hwSubDevs.end()){
		int onlinestatus = arg["online_status"].asInt();
		 int product_id = arg["product_id"].asInt();
		if(onlinestatus == 2){
			EH::Json::Value payload;
			payload["mac"] = sn; 
			payload["product_id"] = subDevIt->second->dev_model_id;
			payload["state"] = 3;  //设备无响应即离线
			sendtoRoma(payload,respTopic_1);  //推送新设备到Roma //在线状态的推送 ，待更改 2020.10.15.9
			subDevIt->second->online = false;
		}else{
			EH::Json::Value payload;
			payload["mac"] = sn; 
			payload["product_id"] = subDevIt->second->dev_model_id;
			payload["state"] = 1;  //设备在线  
			sendtoRoma(payload,respTopic_1);  //推送新设备到Roma
			subDevIt->second->online = true;
		}
		LOGI("hw subdev:%s product_id:%d update online_status:%d.\n",sn.c_str(),product_id, onlinestatus);
	}else{
		LOGW("not found hw subdev:%s for update online_status.\n",sn.c_str());
	}
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}

}

void MQ_CCU_Adapter::handleSyncInfo(EH::Json::Value arg,string opcode) {
	try {
	LOGD("handleSyncInfo:\n   opcode:%s \n   arg:%s.\n",opcode.c_str(),EH_ToolKit::JsonToString(arg).c_str());
	EH::Json::Value deviceStatusArray = arg["device_status"];//设备的状态
	map<string,EH::Json::Value> nodeIdStatusMap;
	 for (int i = 0;i < deviceStatusArray.size();i++){
		EH::Json::Value devStatus = deviceStatusArray[i];
		string opcode = devStatus["opcode"].asString();
		string nodeid = EH_ToolKit::IntToString(devStatus["nodeid"].asInt());
		nodeIdStatusMap[nodeid] = devStatus["arg"];
	}
	//	异常处理：对房间信息进行读取，判断特定房间是否还在，否 ，进入异常处理。
	if(opcode == "SYNC_INFO_PUSH"){
		EH::Json::Value rooms = arg["rooms"];
		Specific_rooms(rooms);
	}

	//添加到房间的子设备
	EH::Json::Value devices = arg["devices"];
	int devCount = devices.size();
	for (int i = 0; i < devCount; i++) {
		EH::Json::Value device = devices[i];
		string operateType = device["operate_type"].asString();
		string nodeid = device["nodeid"].asString();
		string mac = device["mac"].asString();
		string devsn = Replace(mac,":","");
		string channel = device["channel"].asString();
		string devroomid = device["room_id"].asString(); //房间号
		string devname = device["name"].asString(); //设备的名称
		nodeId2channelMap[nodeid] = mac+"_"+channel;

		EH::Json::Value status;
		map<string,EH::Json::Value>::iterator it = nodeIdStatusMap.find(nodeid);
		if(it!=nodeIdStatusMap.end()){
			status = it->second;
		}
		map<string,kk_handleDeviceInfo::KKDevmapinfo>::iterator devIt = hwBindDevMap.find(mac);

		if(devIt!=hwBindDevMap.end()){
			kk_handleDeviceInfo::KKDevmapinfo tripInfo = devIt->second;
			handleCcuDeviceToHwSubDev(operateType,nodeid,mac,channel,devsn,status,devroomid,devname);
		}else{
			LOGD("ccu dev:%s not found  bind info in lcoal cache.delete fron ccu later. \n",mac.c_str());
		}
	}

	// //添加到房间的中央空调网关信息同步
	// EH::Json::Value CentralAcGwsDevices = arg["central_ac_gws"];
	// SYNC_handle_AcGw_Devices(CentralAcGwsDevices);

	//添加到房间的中央空调内机信息同步
	EH::Json::Value CentralAcindoorunits = arg["central_ac_indoorunits"];
	int indoorunitsCount = CentralAcindoorunits.size();
	if(indoorunitsCount > 0){
		int infocome = 1 ;
		string devroomid = "1" ;//临时默认
		string devname = "内机";
		// handleACindoor(devroomid,devname,indoorunitsCount,CentralAcindoorunits,infocome);
	}
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}

}
//处理新设备
void MQ_CCU_Adapter::handleNewDevice(EH::Json::Value devices, EH::Json::Value centralACdevices, EH::Json::Value newCentralAcGwsDevices) {
	try {
		LOGD("handleNewDevice:\n   devices:%s\n   centralACdevices:%s\n   newCentralAcGwsDevices:%s\n",EH_ToolKit::JsonToString(devices).c_str(),
			EH_ToolKit::JsonToString(centralACdevices).c_str(),EH_ToolKit::JsonToString(newCentralAcGwsDevices).c_str());
	int devCount = devices.size();
	int indoorunitsdevCount = centralACdevices.size();//中央空调内机数目
	string devroomid = "-1";
	string devname = "新dev";

	map<string,kk_handleDeviceInfo::HwSubDev*> toAddSubDevs;

	for (int i = 0; i < newCentralAcGwsDevices.size(); i++) {  //有多少个空调网关，要放在处理新设备的前面。
		EH::Json::Value gw = newCentralAcGwsDevices[i];
		string gwId = gw["id"].asString();
		string gwNodeId = gw["bind_central_ac_gw_node_id"].asString();
		gwId2NodeId[gwId] = gwNodeId;
		NodeId2gwId[gwNodeId] = gwId;
		LOGD("add ccu system gwId:%s, gwNodeId:%s \n",gwId.c_str() ,gwNodeId.c_str());
	}


	for (int i = 0; i < devCount; i++) {
		EH::Json::Value device = devices[i];
		string operateType = device["operate_type"].asString();
		string nodeid = device["nodeid"].asString();
		string mac = device["mac"].asString();
		string devsn = Replace(mac,":","");
		string channel = device["channel"].asString();
		string Joinproductid;
		nodeId2channelMap[nodeid] = mac+"_"+channel;


		if(operateType == "12001"){ //中央空调网关
			operate2NodeId[nodeid] = operateType;
		}

		EH::Json::Value status = device["status"]["arg"];
		if(!ccuDeleteMacs.empty() && ccuDeleteMacs.find(mac)!=ccuDeleteMacs.end()){
			continue;
		}

		map<string,kk_handleDeviceInfo::KKDevmapinfo>::iterator it = hwBindDevMap.find(mac);

		if(it!=hwBindDevMap.end()){
			kk_handleDeviceInfo::KKDevmapinfo tripInfo = it->second;
			LOGD("mac:%s in hwBindDevMap  \n",mac.c_str());
			handleCcuDeviceToHwSubDev(operateType,nodeid,mac,channel,devsn,status,devroomid,devname);
		}else{
			map<string,string>::iterator Join_productid = Join_productid_Map.find(mac); //未添加过的，进行添加进入
			if(Join_productid != Join_productid_Map.end()){
				Joinproductid = Join_productid->second;
			}else{
				Joinproductid = "当前未接入设备";
			}
			if(KKdiscover && kk_handleDeviceInfo::GetInstance()->isValidJoinDeviceType(operateType,Joinproductid,mac)){  //KKdiscover 小K或华为点开组网可以进入组网状态
				if(toAddSubDevs.find(mac) != toAddSubDevs.end()){
					LOGD("mac: %s in toAddSubDevs \n",mac.c_str());
					kk_handleDeviceInfo::KKChannelDev* chanDev =  kk_handleDeviceInfo::GetInstance()->buildChannelDevice(operateType,nodeid,channel,status,devroomid,devname);
					kk_handleDeviceInfo::HwSubDev* dev= toAddSubDevs[mac];
					if(chanDev!=NULL){
						dev->channelDevs[channel] = chanDev;
						LOGD("add dev:%s, channel:%s to subdev for add to huawei cloud later.\n",mac.c_str(),channel.c_str());
					}
				}else{
					EH::Json::Value devProductinfo = kk_handleDeviceInfo::GetInstance()->XiaoK_Zu_Wang(Joinproductid);
					kk_handleDeviceInfo::HwSubDev* dev = new kk_handleDeviceInfo::HwSubDev();
					dev->dev_model_id = devProductinfo["dev_model_id"].asString();
					// dev->dev_type = devProductinfo["dev_type"].asString();
					dev->mac = mac;
					dev->operatetype = operateType;
					dev->sn = devsn;
					kk_handleDeviceInfo::KKChannelDev* chanDev = kk_handleDeviceInfo::GetInstance()->buildChannelDevice(operateType,nodeid,channel,status,devroomid,devname);
					map<string,kk_handleDeviceInfo::KKChannelDev*> channelDevs;
					if(chanDev!=NULL){
						channelDevs[channel] = chanDev;
					}
					dev->channelDevs = channelDevs;
					toAddSubDevs[mac] = dev;
					LOGD("found JoinDevProductkey for dev:%s,operateid:%s,channel:%s,. \n",mac.c_str(),operateType.c_str(),channel.c_str());
				}
			}else{
				ccuDeleteMacs.insert(mac);
				LOGW("ccu dev:%s not valid to add.\n",mac.c_str());
			}
		}
	}
	addCCuDevicesToCloud(toAddSubDevs);
	LOGD("after handle NEW_DEVICES,total hw dev count is:%d \n",hwSubDevs.size());
	//deleteCCuDevices(ccuDeleteMacs); //调试
	ccuDeleteMacs.clear();

	//2021.3.34 当前未接入空调，先注释
	// if(indoorunitsdevCount > 0){//有内机的话，单独进行处理
	// 	int infocome = 0 ;//infocome = 0为新设备列表里的
	// handleACindoor(devroomid,devname,indoorunitsdevCount,centralACdevices,infocome);
	// }
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
}


void MQ_CCU_Adapter::handleCcuDeviceToHwSubDev(string operateType,string nodeid,string mac,
		string channel,string sn,EH::Json::Value status,string devroomid,string devname){
	try {		
	LOGD("handleCcuDeviceToHwSubDev operateType:%s  nodeid:%s  channel:%s  sn:%s. \n",operateType.c_str(),nodeid.c_str(),channel.c_str(),sn.c_str());
	map<string,kk_handleDeviceInfo::HwSubDev*>::iterator subDevIt = hwSubDevs.find(sn);

	if(subDevIt == hwSubDevs.end()){//add new dev in cache
		kk_handleDeviceInfo::HwSubDev* dev = new kk_handleDeviceInfo::HwSubDev();
		map<string,kk_handleDeviceInfo::KKDevmapinfo>::iterator devIt = hwBindDevMap.find(mac);
		kk_handleDeviceInfo::KKDevmapinfo tripInfo = devIt->second;
		dev->dev_model_id = tripInfo.dev_model_id;
		// dev->dev_type = tripInfo.dev_type;
		dev->sn = sn;
		dev->mac = mac;
		dev->operatetype = operateType;

		kk_handleDeviceInfo::KKChannelDev* chanDev = kk_handleDeviceInfo::GetInstance()-> buildChannelDevice(operateType,nodeid,channel,status,devroomid,devname);
		map<string,kk_handleDeviceInfo::KKChannelDev*> channelDevs;
		if(chanDev!=NULL){
			channelDevs[channel] = chanDev;
		}
		dev->channelDevs = channelDevs;
		hwSubDevs[sn] = dev;
		// if(KK_HwSdk::GetInstance()->registerNewDev(dev) == 0){  //下一行临时更改，上报设备状态  ，待更改 2020.10.15.9 //解开  2020.12.14.9 
		if(1){
			LOGI("registerdev success.dev:%s, first add to local cache.channel:%s.\n",mac.c_str(),channel.c_str());
		}else{
			hwSubDevs.erase(sn);
			LOGW("registerdev failed. \n");
		}
	}else{
		map<string,kk_handleDeviceInfo::KKChannelDev*> channelDevs = subDevIt->second->channelDevs;
		if(channelDevs.find(channel) == channelDevs.end()){//new node
			kk_handleDeviceInfo::KKChannelDev* chanDev = kk_handleDeviceInfo::GetInstance()->buildChannelDevice(operateType,nodeid,channel,status,devroomid,devname);
			if(chanDev!=NULL){
				subDevIt->second->channelDevs[channel] = chanDev;
			}
			LOGD("dev:%s has added to local cache.try to handle channel:%s  dev info. \n",mac.c_str(),channel.c_str());
		}
	}

	//当这个通道设备未添加到房间，调用这个接口。
	if(devroomid == "-1"){
		map<string,kk_handleDeviceInfo::HwSubDev*>::iterator DevicesToRoom = hwSubDevs.find(sn);
		LOGD("添加到房间 discoveryEnable:%d,KKdiscover:%d,  sn:%s\n",discoveryEnable,KKdiscover,sn.c_str());
		kk_handleDeviceInfo::GetInstance()->addCCuDevicesToRoom(DevicesToRoom,NodeId2gwId); //自动添加华为组设备。
	}
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
}


void MQ_CCU_Adapter::addCCuDevicesToCloud(map<string,kk_handleDeviceInfo::HwSubDev*> toAddSubDevs){	
	try {
		LOGI("prepare to add %d   new devices to Roma cloud.\n",toAddSubDevs.size());
		string respTopic ;
			respTopic= pushTopic + string("/device/new");//子设备入网
		if(toAddSubDevs.empty()){
			return ;
		}
		set<string> addFailedDevs;
		for(map<string,kk_handleDeviceInfo::HwSubDev*>::iterator it = toAddSubDevs.begin();it!=toAddSubDevs.end();it++){
			int ret;
			EH::Json::Value payload;
			string devMac = it->first;
			string dev_model_id = it->second->dev_model_id;

			LOGI("prepare to add dev:  %s  ,dev_model_id:  %s. \n",devMac.c_str(),dev_model_id.c_str());
			it->second->online = true;
			mtx.acquire();
			string devSn =  it->second->sn;
			//是否已经加入映射列表里
			map<string, kk_handleDeviceInfo::HwSubDev*>::iterator subDevIt = hwSubDevs.find(devSn);
			if(subDevIt != hwSubDevs.end() && (dev_model_id == DAIKINCentralACindoor_PID||dev_model_id == DAIKINCentralACgw_PID)){//空调内机，重复推送入网会有问题，改为推上线。
				// respTopic= pushTopic + string("/deviceonline");
				// payload["mac"] = devSn;
				// payload["product_id"] = it->second->dev_model_id;
			}else{
				payload["mac"] = devSn;
				payload["product_id"] = it->second->dev_model_id;
			}
			ret = sendtoRoma(payload,respTopic);  //推送新设备到Roma
			if(ret == 0){
				LOGI("add device:%s,dev_model_id:%s,to Roma cloud success!!!\n",devMac.c_str(),dev_model_id.c_str());
			//添加到映射列表里
			hwSubDevs[devSn] = it->second; //add to cache;
			LOGD("add to cache devSn :%s.\n", devSn.c_str());

			// if(discoveryEnable == true && KKdiscover == true){//小K 华为组网时，自动添加设备到特定房间里。
				LOGD("       添加到房间       discoveryEnable:%d ,  prodId:%d\n",discoveryEnable,KKdiscover);
				kk_handleDeviceInfo::GetInstance()->addCCuDevicesToRoom(it,NodeId2gwId);
			// }
				mtx.release();

				if(dev_model_id == DAIKINCentralACindoor_PID){
				continue; //使得内机都可以添加进入
				}

				client->sendRequest(gw_NodeId, "CLOSE_NET_CHANNEL", "*", "HJ_Server");
				this->discoveryEnable = false;
			}else{
				hwSubDevs.erase(devSn);
				mtx.release();
				addFailedDevs.insert(devMac);
				LOGE("add dev:%s to hw cloud failed.\n",devMac.c_str());
			}
		}
		this->discoveryEnable = false;
		LOGD("discoveryEnable:%d,\n",discoveryEnable);
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}

}

//发送添加房间命令
void MQ_CCU_Adapter::SendSETUPToCcu(string name,string DeviceIcon,string DevDodeId,string roomid,string opcode){
	string arg;
	if(opcode == "SETUP_NODE"){  
		EH::Json::Value devicearg;
		devicearg["name"] = name;
		devicearg["device_icon"] = DeviceIcon;
		devicearg["device_pos"] = "1";
		devicearg["room_id"] = roomid;
		arg = EH_ToolKit::JsonToString(devicearg);
	}else if(opcode == "SET_CENTRAL_AC_INDOOR_UNIT"||opcode == "SET_CENTRAL_AC_GW"){
		EH::Json::Value devicearg;
		devicearg["name"] = name;
		devicearg["room_id"] = roomid;
		arg = EH_ToolKit::JsonToString(devicearg);
	}
	client->sendRequest(DevDodeId,opcode, arg, "HJ_Config");
}

void MQ_CCU_Adapter::oninitmqttsdk() {
	try {
	//goto跳转，谨慎使用。
	// loop:
		string heartbeat_Topic;
		clientId = "123456";
		username = "123456";

		//订阅的 Topic
		pushTopic = string("$xlink/ptp/")+gw_id; //ptp
		subTopic  = string("$xlink/ptp/")+gw_id;  //ptp交互
		PTPO_Topic  = string("$xlink/ptpo/")+gw_id;  //ptpo运维
		willTopic = string("xChfVJ501599/out/")+username+"/heartbeat";  //遗嘱信息
		heartbeat_Topic = string("$xlink/ptp/")+gw_id+"/ptp_keepalive"; //心跳
		LOGD("pushTopic is: %s  subTopic is: %s  willTopic is: %s\n",pushTopic.c_str(),subTopic.c_str(),willTopic.c_str());

		// int ret =  mqttSdk->init("172.25.240.31:1983",  //临时调试环境
		// 		clientId,"SmartMonitor","k9CCGgJZlkKhVottLvN0EVBOMc1sCC",willTopic,heartbeat_Topic,gw_id); //与云智易的XCG建立连接除了IP以外都不需要。
		int ret =  mqttSdk->init("127.0.0.1:23883",  //正式环境
				clientId,"2CEDC38940644E439649389C08329B09","}A12a#RM^r)iXy/?|sHW:z3!",willTopic,heartbeat_Topic,PTPO_Topic,gw_id); //与云智易的XCG建立连接除了IP以外都不需要。
		mqttOnline = false;
		if(ret == 0){
			mqttSdk->con(1,3);
		}else{
			LOGE("init mqtt sdk failed.\n");
			return;
		}
		// LOGI("与APP未绑定 Not bound to app\n");
		// sleep(1);
		// goto loop;
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
}

//---mqtt broker communication  mqtt代理通信
//云上连接
void MQ_CCU_Adapter::onCloudConnect(){
	LOGI("mqtt 代理 通信 云上连接 .\n");
	LOGI("onCloudConnect,to sub topic.\n");
	EH::Json::Value online;
	online["gw_id"] = gw_id;
	if(mqttSdk->subTopic(subTopic,0,2000)!=0){
		LOGW("sub topic:%s failed,exit now.\n",subTopic.c_str());
		ACE_OS::sleep(1);
		ACE_OS::exit(1);
	}else{
		LOGD("sub topic Many success,ready to work.\n");
		mqttSdk->sendMsg(willTopic,EH_ToolKit::JsonToString(online),0);
		if(mqttOnline == false){  //与云端断开重联才会发送，达到同步设备信息。
			string arg = "{\"conditions\":[{\"condition_type\":\"dev_list\",\"condition_arg\":[]}]}";
			client->sendRequest("*", "GET_ZIGBEE_DEVS_HW_INFO", arg, "HJ_Config");
			mqttOnline = true;
		}
	}
}

//云端断开连接
void MQ_CCU_Adapter::onCloudDisConnect(){
	mqttOnline = false;
	LOGW("云端 断开 连接 .\n");
	LOGW("onCloudDisConnect,reconnect in seconds.\n");
}


//删除请求
int MQ_CCU_Adapter::onDeviceRequestDelete(string devSn){
	try {
		LOGD("删除设备:%s .\n",devSn.c_str());
		Deletesn = devSn;
		mtx.acquire();
		map<string,kk_handleDeviceInfo::HwSubDev*>::iterator it = hwSubDevs.find(devSn);
		if(it != hwSubDevs.end()){
			string channel= "1";
			string DevDodeId;		
			string devMac = it->second->mac;
			string devProdId = it->second->dev_model_id;
			hwSubDevs.erase(devSn);
			if(devProdId == DAIKINCentralACindoor_PID){  //内机特殊处理
				LOGD("删除内机设备:%s .\n",devSn.c_str());
				mtx.release();
				return 0;
			}
			hwBindDevMap.erase(devMac);
			//KK_HwDevManager::GetInstance()->saveAllSubDev(hwBindDevMap);

			if (devProdId == DAIKINCentralACgw_PID) {
				// string gwNodeId = KK_CcuConfig::GetInstance()->getCentralAcGwNodeId(it->second->mac);
				// sendReqToCcu("DEL_CENTRAL_AC_GW",gwNodeId,"*","HJ_CentralAC");
				map<string,string>::iterator gwIt = NodeId2gwId.find(it->second->channelDevs["1"]->nodeId); //NodeId2gwId  gwId2NodeId
				if(gwIt == NodeId2gwId.end()){
					LOGW("centralACnodeId:%s not in gwId2NodeId.\n",it->second->channelDevs["1"]->nodeId.c_str());
				} else {
					DevDodeId = gwIt->second;
				}
				client->sendRequest(DevDodeId, "DEL_CENTRAL_AC_GW", "*", "HJ_CentralAC");
				onACindoorDelete(devMac);
			} else {
				string arg = "{\"mac\":\""+devMac+"\"}";
				sendReqToCcu("DEL_DEVICE","*",arg,"HJ_Server");

				//子设备解绑或移除
				string respTopic;
				respTopic = pushTopic+"/device/left";
				EH::Json::Value payload;
				payload["product_id"] = devProdId;
				payload["mac"] = devSn;
				int SendOk;
				SendOk = sendtoRoma(payload,respTopic);
			}
		}else{
			LOGW("not found hw dev:%s in local triple cache.\n",devSn.c_str());
		}
		mtx.release();
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
	return 0;
}

//小K 删除
int  MQ_CCU_Adapter::loadDelete(EH::Json::Value arg){
	try {
	string devSn = Replace(arg.asString(),":","");
	if(Deletesn == devSn){   //兴海app删
		Deletesn = "";
	}else{                   //小K app删
		mtx.acquire();
		map<string, kk_handleDeviceInfo::HwSubDev*>::iterator it = hwSubDevs.find(devSn);
		if(it != hwSubDevs.end()){
			string channel= "1";
			string devMac = it->second->mac;
//			KK_HwSdk::GetInstance()->changeDevOnline(devSn, false);
			it->second->online = false;
			if(it->second->dev_model_id == DAIKINCentralACgw_PID){
				// handleACindoorDevNolinePush(arg.asString());
			}
			LOGI("本地删除设备sn:%s    推送设备离线:%s.\n",devSn.c_str(),devSn.c_str());
			hwSubDevs.erase(devSn);
			hwBindDevMap.erase(devMac);
			//子设备解绑或移除
			string respTopic;
			respTopic = pushTopic+"/device/left";//子设备删除
			EH::Json::Value payload;
			payload["mac"] = devSn; //请求发起者
			payload["product_id"] = it->second->dev_model_id;
			sendtoRoma(payload,respTopic);
		}else{
			LOGW("这个设备已删除，不推送.\n");
		}
		mtx.release();
	}
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
	return 0;
}
//删除空调网关时，也删除其下的内机。
int MQ_CCU_Adapter::onACindoorDelete(string devMac){
	string sn;
	try {
	map<string,vector<string> >::iterator numIt = controllerModel.find(devMac);
	if (numIt != controllerModel.end()) {
		for (vector<string>::iterator it = numIt->second.begin(); it != numIt->second.end(); it++) {
		 sn = (*it).c_str();
			//子设备解绑或移除
			string respTopic;
			respTopic = pushTopic+"/deviceoffline";//子设备离线
			EH::Json::Value payload;
			payload["dev_id"] = sn; //请求发起者
			sendtoRoma(payload,respTopic);  //网关离线，内机向华为推送离线。  //删除空调网关也会删除内机,
			LOGI("删除内机sn:%s .\n",sn.c_str());
			hwSubDevs.erase(sn);
		}
	}else{
		LOGD("这个中央空调网关没有内机.\n");
	}
	}catch (exception &e) {
		LOGW("%s.\n", e.what());
	}
	return 0;
}

// //空调内机在线离线推送
// void MQ_CCU_Adapter::handleACindoorDevNolinePush(string mac){
// 	try {
// 		string sn;
// 		map<string,vector<string> >::iterator numIt = controllerModel.find(mac);
// 		if (numIt != controllerModel.end()) {
// 			for (vector<string>::iterator it = numIt->second.begin(); it != numIt->second.end(); it++) {
// 				EH::Json::Value idJson;
// 				sn = (*it).c_str();
// 				map<string, kk_handleDeviceInfo::HwSubDev*>::iterator subDevIt = hwSubDevs.find(sn);

// 				//子设备解绑或移除
// 				string respTopic;
// 				respTopic = pushTopic + "/deviceoffline";//子设备离线
// 				EH::Json::Value payload;
// 				payload["dev_id"] = sn; //请求发起者
// 				sendtoRoma(payload,respTopic);  //网关离线，内机向华为推送离线。  //删除空调网关也会删除内机,
// 				subDevIt->second->online = false;
// 				LOGI("删除内机sn:%s .\n",sn.c_str());
// 				hwSubDevs.erase(sn);
// 			}
// 		}
// 	}catch (exception &e) {
// 		LOGW("%s.\n", e.what());
// 	}
// }

int MQ_CCU_Adapter::sendtoRoma(EH::Json::Value payload,string respTopic){
	LOGD("send to Roma msg payload:%s respTopic:%s.\n",payload.toStyledString().c_str(),respTopic.c_str());
	EH::Json::FastWriter writer;
	string sendPayload = writer.write(payload);
	return mqttSdk->sendMsg(respTopic,sendPayload,0);
}

//获取网关的nodeID
void MQ_CCU_Adapter::handlegwNodeId(EH::Json::Value arg){
	EH::Json::Value gw_lists = arg["gw_list"];
	for(int i = 0;i < gw_lists.size();i++){
		EH::Json::Value gw_list = gw_lists[i];
		if(gw_list["gw_type"] == "6"&&gw_list["gw_link"] == "1"){ //Z3网关类型且在线。
			gw_NodeId = gw_list["gw_nodeid"].asString();
		}
	}

}

//加载主机所有已经添加的设备
int MQ_CCU_Adapter::loadAllSubDev(EH::Json::Value arg){
	try {
		if(arg.isArray()){
			for(int i = 0;i < arg.size();i++){
				kk_handleDeviceInfo::KKDevmapinfo bindDev;
				bindDev.mac = arg[i]["mac"].asString();
				bindDev.sn = Replace(bindDev.mac,":","");
				string productid = EH_ToolKit::IntToString(arg[i]["product_id"].asInt());
				EH::Json::Value XiaoKprodId = kk_handleDeviceInfo::GetInstance()->XiaoK_Zu_Wang(productid); //调用设备是否接入华为
				if ( XiaoKprodId["dev_model_id"] != "-1"){
					bindDev.dev_model_id = XiaoKprodId["dev_model_id"].asString();
					// bindDev.dev_type = XiaoKprodId["dev_type"].asString();
				}else {
					continue;
				}
				LOGD("all_devs_info mac:%s productid:%s  dev_model_id:%s.\n",arg[i]["mac"].asString().c_str(),productid.c_str(),XiaoKprodId["dev_model_id"].asString().c_str());
				hwBindDevMap[bindDev.mac] = bindDev;
				}
			}
	} catch (exception& e) {
			LOGW("%s.\n",e.what());
		}
	LOGI("load all sub dev,now dev count:%d.\n", hwBindDevMap.size());
	return 0;
}

//Zigbee 设备入网推送的信息
int MQ_CCU_Adapter::handle_Dev_Join_Notify(EH::Json::Value arg){
	try {
	//新加入设备mac -> 设备productid
		if(Join_productid_Map.size()>50){  //临时方案，待优化，是个隐藏bug:一次组多个设备且在程序启动后的50次左右
			Join_productid_Map.clear(); //新设备添加完成去除
		}
		string dev_mac = arg["mac"].asString();
		string dev_productid = EH_ToolKit::IntToString(arg["productId"].asInt());
		Join_productid_Map[dev_mac] = dev_productid;
	} catch (exception& e) {
		LOGW("%s.\n",e.what());
	}
	return 0;
}


// //开始处理空调内机
// void MQ_CCU_Adapter::handleACindoor(string devroomid,string devname,int indoorunitsdevCount,EH::Json::Value centralACdevices,int infocome){
// 	try {
// 	LOGD("开始处理空调内机\n");
// 	int error;
// 	map<string,kk_handleDeviceInfo::HwSubDev*> toAddSubDevs;//需要添加到华为的设备信息。

// 	controllerModel.clear();
// 	for (int i = 0; i < indoorunitsdevCount; i++) { ////中央空调内机数目
// 		string channel= "1";
// 		EH::Json::Value centralAC = centralACdevices[i];
// 		string indoorunitId = centralAC["id"].asString();
// 		string indoorunitAddr = centralAC["indooruint_addr"].asString();
// 		string centralACGwId;//中央空调网关设备 ID，注：非 zigbee 设备 ID 体系
// 		EH::Json::Value indoorunitStatus;//内机当前的状态

// 		if(infocome == 0){ 												//infocome = 0为新设备列表里的，=1表示为添加到房间里了。
// 			centralACGwId = centralAC["bind_central_ac_gw_node_id"].asString();//
// 			indoorunitStatus = centralAC["status"];
// 		}else if(infocome == 1){
// 			centralACGwId = centralAC["central_ac_gw_devid"].asString();//中央空调网关设备 ID，注：非 zigbee 设备 ID 体系
// 			devroomid = centralAC["room_id"].asString(); 				//房间号
// 			indoorunitStatus = centralAC["indoorunit_state"]; 			//内机当前的状态
// 			devname =centralAC["indoorunit_name"].asString(); 		//内机的名称，不同步到华为。
// 		}

// 		string centralAcGwNodeId;     //这个内机对应的空调网关ID
// 		string centralACGwMac;        //这个内机对应的空调网关Mac
// 		string centralACGwoperateType;   //这个内机对应的空调网关类型
// 		string centralACindoorMac;        //这个内机mac为空调网关Mac+id
// 		string centralACindoorsn;		//这个内机sn为空调网关Mac+id 去除“：”

// 		//1。 这个内机对应的空调网关ID
// 		LOGD("centralACGwId:%s,indoorunitAddr:%s,indoorunitnodeId:%s \n",centralACGwId.c_str(),indoorunitAddr.c_str(),indoorunitId.c_str());
// 		map<string,string>::iterator gwIt = gwId2NodeId.find(centralACGwId);
// 		if(gwIt == gwId2NodeId.end()){
// 			LOGW("centralACGwId:%s not in gwId2NodeId.\n",centralACGwId.c_str());
// 			continue;
// 		} else {
// 			centralAcGwNodeId = gwIt->second;
// 		}
// 		//2。 这个内机对应的空调网关类型
// 		map<string,string>::iterator operateIt = operate2NodeId.find(centralAcGwNodeId);
// 		if(operateIt == operate2NodeId.end()){
// 			LOGW("centralAcGwNodeId:%s not in operate2NodeId.\n",centralAcGwNodeId.c_str());
// 			continue;
// 		} else {
// 			centralACGwoperateType = "-13"; //情景模式里的内机operateId
// 		}
// 		//3。 这个内机对应的空调网关Mac
// 		map<string,string>::iterator centralAcNodeIt = nodeId2channelMap.find(centralAcGwNodeId);
// 		if(centralAcNodeIt == nodeId2channelMap.end()){
// 			LOGW("nodeid:%s not in nodeId2channelMap.\n",centralAcGwNodeId.c_str());
// 			continue;
// 		} else {
// 			vector<string> chanMac;
// 			Split(centralAcNodeIt->second,"_",chanMac);
// 			centralACGwMac = chanMac[0];
// 		}
// 		indoorunitsId2AddrMap[indoorunitId] = centralACGwMac+"_"+indoorunitAddr; //网关与内机通道id之间的对应关系
// 		LOGD("indoorunitId:%s .\n",indoorunitId.c_str());
// 		if(StringToInt(indoorunitAddr,error)<10){
// 		centralACindoorMac = centralACGwMac+"0"+indoorunitAddr;		//*****************内机的mac构成关系
// 		}else{
// 		centralACindoorMac = centralACGwMac+indoorunitAddr;
// 		}
// 		centralACindoorsn = Replace(centralACindoorMac,":","");     //*****************内机的sn
// 		if(!ccuDeleteMacs.empty() && ccuDeleteMacs.find(centralACGwMac)!=ccuDeleteMacs.end()){
// 			continue;
// 		}

// 		map<string,vector<string> >::iterator numIt = controllerModel.find(centralACGwMac);//说明待定
// 		if (numIt == controllerModel.end()) {
// 			vector<string> addrId;
// 			addrId.push_back(centralACindoorsn);
// 			controllerModel[centralACGwMac] = addrId;
// 		} else {
// 			numIt->second.push_back(centralACindoorsn);
// 		}

// 		map<string,kk_handleDeviceInfo::KKDevmapinfo>::iterator it = hwBindDevMap.find(centralACindoorMac);

// 		if(it!=hwBindDevMap.end()){
// 			kk_handleDeviceInfo::KKDevmapinfo  tripInfo = it->second;
// 			LOGD("centralACGwMac:%s in hwBindDevMap  \n",centralACindoorMac.c_str());
// 			handleCcuDeviceToHwSubDev(centralACGwoperateType,indoorunitId,centralACindoorMac,channel,tripInfo.sn,indoorunitStatus,devroomid,devname);
// 		}else{
// 			if(toAddSubDevs.find(centralACindoorMac) == toAddSubDevs.end()){
// 				kk_handleDeviceInfo::HwSubDev* dev = new kk_handleDeviceInfo::HwSubDev();
// 				dev->dev_model_id = DAIKINCentralACindoor_PID; //内机 对应的华为prodID
// 				dev->dev_type = DAIKINCentralACindoor_PID;
// 				dev->mac = centralACindoorMac;
// 				dev->operatetype = centralACGwoperateType;
// 				dev->sn = Replace(centralACindoorMac,":","");
// 				kk_handleDeviceInfo::KKChannelDev* chanDev = kk_handleDeviceInfo::GetInstance()->buildChannelDevice(centralACGwoperateType,indoorunitId,channel,indoorunitStatus,devroomid,devname);
// 				map<string,kk_handleDeviceInfo::KKChannelDev*> channelDevs;
// 				if(chanDev!=NULL){
// 					channelDevs[channel] = chanDev;
// 				}
// 				dev->channelDevs = channelDevs;
// 				toAddSubDevs[centralACindoorMac] = dev;
// 				LOGD("\n found JoinDevProductkey for dev:%s,operateid:%s,channel:%s,close zigbee net now. \n",
// 						centralACindoorMac.c_str(),centralACGwoperateType.c_str(), channel.c_str());
// 			}
// 		}
// 	}

// //	空调网关数量及内机地址推送
// //	map<string, string> hwCentralAcList;
// //	for(map<string, string>::iterator addrIt = indoorunitsId2AddrMap.begin(); addrIt!=indoorunitsId2AddrMap.end(); addrIt++){
// //		vector<string> macChan;
// //		Split(addrIt->second,"_", macChan);
// //		EH::Json::Value batchArg;
// //		hwCentralAcList[macChan[0]] = macChan[1];
// //	}
// 	if( toAddSubDevs.size() > 0){
// 		discoveryEnable = true;
// 		KKdiscover = true;
// 		LOGD("                                  discoveryEnable:%d,KKdiscover:%d\n",discoveryEnable,KKdiscover);
// 	}
// 	addCCuDevicesToCloud(toAddSubDevs);
// 	LOGD("after handle NEW_DEVICES,total hw dev count is:%d \n",hwSubDevs.size());
// 	//推送内机数目
// 	for(map<string, string>::iterator gwIt = gwId2NodeId.begin(); gwIt!=gwId2NodeId.end(); gwIt++){
// 		map<string,string>::iterator nodeIt = nodeId2channelMap.find(gwIt->second);
// 		if(nodeIt == nodeId2channelMap.end()){
// 			LOGW("gwId:%s not in gwId2NodeId, affect Internal machine push.\n",gwIt->second.c_str());
// 			continue;
// 		}
// 		vector<string> chanMac;
// 		Split(nodeIt->second,"_",chanMac);
// 		string sn = Replace(chanMac[0],":","");
// 		string channel = chanMac[1];
// 		map<string, kk_handleDeviceInfo::HwSubDev*>::iterator subDevIt = hwSubDevs.find(sn);
// 		if(subDevIt == hwSubDevs.end()){
// 			LOGW("dev:%s not in hwSubDevs.\n",sn.c_str());
// 			continue;
// 		} else {
// 			string dev_model_id = subDevIt->second->dev_model_id;
// 			string devType = subDevIt->second->devTypeId;
// 			EH::Json::Value payload;
// 			EH::Json::Value msgstate0;
// 			payload["gw_id"] = EH_ToolKit::GetMacNoSpace(); //请求发起者
// 			payload["dev_id"] = sn;
// 			payload["dev_type"] = subDevIt->second->dev_model_id;
// 			payload["dev_ep_id"] = StringToInt(channel,error); //通道
// 			EH::Json::Value msgstate2;
// 			string respTopic = pushTopic+string("/devicestatechange");//设备状态变化上报
// 			EH::Json::Value array;
// 			map<string,vector<string> >::iterator numIt = controllerModel.find(subDevIt->second->mac);
// 			if (numIt != controllerModel.end()) {
// 				for (vector<string>::iterator it = numIt->second.begin(); it != numIt->second.end(); it++) {
// 					EH::Json::Value idJson;
// 					idJson["sn"] = *it;
// 					array.append(idJson);
// 				}
// 				msgstate2["deviceList"] = array;
// 			} else {
// 				msgstate2["deviceList"].resize(0);//空数组
// 			}
// 			payload["state"] = msgstate2;
// 			payload["dev_ep_id"] = 3; //功能映射为通道3
// 			// MQ_CCU_Adapter::GetInstance()->sendtoRoma(payload,respTopic);
// 		}

// 	}
	
// 	//deleteCCuDevices(ccuDeleteMacs); //调试
// 	ccuDeleteMacs.clear();
// 	}catch (exception &e) {
// 		LOGW("%s.\n", e.what());
// 	}	
// }

//SYNC_INFO 处理中央空调网关
// void MQ_CCU_Adapter::SYNC_handle_AcGw_Devices(EH::Json::Value CentralAcGwsDevices){   
// 	try {
// 	for (int i = 0; i < CentralAcGwsDevices.size(); i++) {
// 		EH::Json::Value Gwdevice = CentralAcGwsDevices[i];
// 		string operateType = "12001";//中央空调网关
// 		string gwId = Gwdevice["id"].asString();
// 		string nodeid = Gwdevice["bind_central_ac_gw_node_id"].asString();
// 		gwId2NodeId[gwId] = nodeid;
// 		NodeId2gwId[nodeid] = gwId;
// 		LOGD("add ccu system gwId:%s, gwNodeId:%s \n",gwId.c_str() ,nodeid.c_str());

// 		operate2NodeId[nodeid] = operateType;

// 		string mac = "未接入以后再改";
// 		// string mac = KK_CcuConfig::GetInstance()->getCentralAcGwMac(nodeid);
// 		string channel = "1";
// 		string devroomid = Gwdevice["room_id"].asString(); //房间号
// 		string devname = Gwdevice["dev_name"].asString(); //设备的名称
// 		nodeId2channelMap[nodeid] = mac+"_"+channel;

// 		EH::Json::Value status = "0"; //设备的状态 Gwdevice["status"].asString()"status": {"gwStatusCode": -1,"online": false}
// 		map<string,kk_handleDeviceInfo::KKDevmapinfo>::iterator devIt = hwBindDevMap.find(mac);

// 		if(devIt!=hwBindDevMap.end()){
// 			kk_handleDeviceInfo::KKDevmapinfo tripInfo = devIt->second;
// 			handleCcuDeviceToHwSubDev(operateType,nodeid,mac,channel,tripInfo.sn,status,devroomid,devname);
// 		}else{
// 			LOGW("ccu dev:%s not found  bind info in lcoal cache.delete fron ccu later. \n",mac.c_str());
// 		}
// 	}
// 	}catch (exception &e) {
// 		LOGW("%s.\n", e.what());
// 	}
// }