Ver código fonte

Merge branch 'dimming_version' of HomeNetServer/kakao into master

alalssg 5 anos atrás
pai
commit
29cf1c4057

+ 19 - 17
src/main/java/com/icontrols/kakao/common/KAKAO_RESULT.java

@@ -4,27 +4,29 @@ import java.util.HashMap;
 import java.util.Map;
 
 public class KAKAO_RESULT {
-	public static final int SUCCESS 			= 200, 
-							FAIL_INTERNAL 		= -200,
-							FAIL_EXPIREDTOKEN 	= -201,
-							FAIL_UNREACHABLE	= -202,
-							FAIL_NONEXIST		= -203,
-							FAIL_THING_INTERNAL	= -204,
-							FAIL_INVALID_REQ	= -205,
-							FAIL_INVALID_TOKEN	= -206,
-							FAIL_INVALID_CLIENT	= -207;
+	public static final int SUCCESS 						= 200, 
+							FAIL_INTERNAL 					= -200,
+							FAIL_EXPIREDTOKEN 				= -201,
+							FAIL_UNREACHABLE				= -202,
+							FAIL_NONEXIST					= -203,
+							FAIL_THING_INTERNAL				= -204,
+							FAIL_INVALID_REQ				= -205,
+							FAIL_INVALID_TOKEN				= -206,
+							FAIL_INVALID_CLIENT				= -207,
+							FAIL_UNLINKEXTENSION_SERVICE 	= -208;
 	
 	public enum CODE {
 		SUCCESS(200, "정상동작", "Success"),
 		
-		FAIL_INTERNAL		(-200, "InternalServerError", 	"내부 서버 에러"),
-		FAIL_EXPIREDTOKEN	(-201, "ExpiredAccessToken", 	"인증토큰 만료"),
-		FAIL_UNREACHABLE	(-202, "ThingUnreachable", 		"Things 연결 실패"),
-		FAIL_NONEXIST		(-203, "ThingNonexistent", 		"정의되지않은 기기 Endpoint"),
-		FAIL_THING_INTERNAL	(-204, "ThingInternalError", 	"기기에서 처리할 수 없는 요청" ),
-		FAIL_INVALID_REQ	(-205, "InvalidRequest", 		"올바르지 않은 요청메세지"),
-		FAIL_INVALID_TOKEN	(-206, "InvalidAccessToken", 	"유효하지 않은 인증토큰"),
-		FAIL_INVALID_CLIENT	(-207, "InvalidClient", 		"Client 인증 실패");
+		FAIL_INTERNAL				(-200, "InternalServerError", 	"내부 서버 에러"),
+		FAIL_EXPIREDTOKEN			(-201, "ExpiredAccessToken", 	"인증토큰 만료"),
+		FAIL_UNREACHABLE			(-202, "ThingUnreachable", 		"Things 연결 실패"),
+		FAIL_NONEXIST				(-203, "ThingNonexistent", 		"정의되지않은 기기 Endpoint"),
+		FAIL_THING_INTERNAL			(-204, "ThingInternalError", 	"기기에서 처리할 수 없는 요청" ),
+		FAIL_INVALID_REQ			(-205, "InvalidRequest", 		"올바르지 않은 요청메세지"),
+		FAIL_INVALID_TOKEN			(-206, "InvalidAccessToken", 	"유효하지 않은 인증토큰"),
+		FAIL_INVALID_CLIENT			(-207, "InvalidClient", 		"Client 인증 실패"),
+		FAIL_UNLINKEXTENSION_SERVICE(-208, "UnlinkExtensionService","Client 인증 실패");
 		
 		private int resultCode;
 		private String message;

+ 72 - 38
src/main/java/com/icontrols/kakao/common/THINGS_INFO.java

@@ -2,21 +2,33 @@ package com.icontrols.kakao.common;
 
 import java.util.Arrays;
 
+import org.slf4j.LoggerFactory;
+
 import com.icontrols.kakao.common.utils.BeanUtils;
 import com.icontrols.kakao.repo.ThingsInfoRepository;
+import com.icontrols.kakao.socket.wallpad.KakaoMsgHandler;
+
+import ch.qos.logback.classic.Logger;
 
 public final class THINGS_INFO {
+	
 	public static final int THINGS_LIGHT 		= 1,  THINGS_TEMPER  	= 2,  THINGS_ELECPLUG 	= 3,  THINGS_GAS 		= 4,
 							THINGS_ILGALSWITCH 	= 5,  THINGS_WALLPAD  	= 6,  THINGS_VENTIL 	= 7,  THINGS_NOTICE 	= 8,
 							THINGS_VOTE			= 9,  THINGS_PARKING  	= 10, THINGS_PARCEL 	= 11, THINGS_HEMS 		= 12,
-							THINGS_CARIN 		= 13, THINGS_ELEVATOR 	= 14, THINGS_VISITOR 	= 15, THINGS_EMERGENCY 	= 16;
+							THINGS_CARIN 		= 13, THINGS_ELEVATOR 	= 14, THINGS_VISITOR 	= 15, THINGS_EMERGENCY 	= 16,
+							THINGS_LIGHT_DIMMER = 17, THINGS_COLOR_LIGHT_DIMMER = 18;
 	
 	public enum THINGS_CAPABILITY{
+		LIVINGLIGHT("livingLight","{\"capabilities\" : [ { \"name\" : \"Power\" } ]}"),
 		LIGHT("light","{\"capabilities\" : [ { \"name\" : \"Power\" } ]}"),
+		LIGHT_DIMMER("dimming","{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Brightness\" } ]}"),
+		COLOR_LIGHT("colorLight", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"ColorMode\"}, { \"name\" : \"ColorTemperature\"} ]}"),
+		COLOR_LIGHT_DIMMER("colorDimming", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Brightness\" }, { \"name\" : \"ColorMode\"}, { \"name\" : \"ColorTemperature\"} ]}"),
 		TEMPER("temper", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Temperature\" }, { \"name\" : \"TemperatureSetpoint\" } ]}"),
 		VENTIL("ventil","{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"AirFlow\" } ]}"),
 		GAS("gas","{\"capabilities\" : [ { \"name\" : \"Lock\" } ] }"),
-		ELEVATOR("elevator", "{\"capabilities\" : [ { \"name\" : \"ElevatorCall\" } ] }");
+		ELEVATOR("elevator", "{\"capabilities\" : [ { \"name\" : \"ElevatorCall\" } ] }"),
+		ELECTRIC("electric", "{\"capabilities\" : [ { \"name\" : \"Power\" } ]}");
 		
 		private String thingsName;
 		private String capJsonStr;
@@ -40,19 +52,34 @@ public final class THINGS_INFO {
 	}
 	
 	public enum DEVICE_DETAIL{
-		LIVINGLIGHT	("livinglight", 	"Light", 			"거실조명"),
-		LIGHT01		("light01",			"Light",			"안방조명"),
-		LIGHT02		("light02",			"Light",			"서재조명"),
-		LIGHT03		("light03",			"Light",			"작은방조명"),
-		LIGHT04		("light04",			"Light",			"주방조명"),
-		VENTIL		("ventil",			"AirVentilator",	"환기"),
-		GAS			("gas",				"GasValve",			"가스밸브"),
-		ELEVATOR	("ElevatorCaller",	"ElevatorCaller",	"엘리베이터"),
-		TEMPER1		("temper_1",		"FloorHeater",		"거실난방"),
-		TEMPER2		("temper_2",		"FloorHeater",		"안방난방"),
-		TEMPER3		("temper_3",		"FloorHeater",		"서재난방"),
-		TEMPER4		("temper_4",		"FloorHeater",		"작은방난방"),
-		TEMPER5		("temper_5",		"FloorHeater",		"주방난방")
+		LIVINGLIGHT					("livinglight", 				"Light", 			"거실조명"),
+		LIGHT01						("light01",						"Light",			"안방조명"),
+		LIGHT02						("light02",						"Light",			"서재조명"),
+		LIGHT03						("light03",						"Light",			"작은방조명"),
+		LIGHT04						("light04",						"Light",			"주방조명"),
+		DIMMER_LIVINGLIGHT			("dimmer_livinglight", 			"LightDimmer", 		"거실조명"),
+		DIMMER_LIGHT01				("dimmer_light01",				"LightDimmer",		"안방조명"),
+		DIMMER_LIGHT02				("dimmer_light02",				"LightDimmer",		"서재조명"),
+		DIMMER_LIGHT03				("dimmer_light03",				"LightDimmer",		"작은방조명"),
+		DIMMER_LIGHT04				("dimmer_light04",				"LightDimmer",		"주방조명"),
+		COLOR_DIMMER_LIVINGLIGHT	("colorDimmer_livinglight", 	"ColorLightDimmer",	"거실조명"),
+		COLOR_DIMMER_LIGHT01		("colorDimmer_light01",			"ColorLightDimmer",	"안방조명"),
+		COLOR_DIMMER_LIGHT02		("colorDimmer_light02",			"ColorLightDimmer",	"서재조명"),
+		COLOR_DIMMER_LIGHT03		("colorDimmer_light03",			"ColorLightDimmer",	"작은방조명"),
+		COLOR_DIMMER_LIGHT04		("colorDimmer_light04",			"ColorLightDimmer",	"주방조명"),
+		VENTIL						("ventil",						"AirVentilator",	"환기"),
+		GAS							("gas",							"GasValve",			"가스밸브"),
+		ELEVATOR					("ElevatorCaller",				"ElevatorCaller",	"엘리베이터"),
+		TEMPER1						("temper_1",					"FloorHeater",		"거실난방"),
+		TEMPER2						("temper_2",					"FloorHeater",		"안방난방"),
+		TEMPER3						("temper_3",					"FloorHeater",		"서재난방"),
+		TEMPER4						("temper_4",					"FloorHeater",		"작은방난방"),
+		TEMPER5						("temper_5",					"FloorHeater",		"주방난방"),
+		ELECTRIC01					("electric01",					"PowerOutlet",		"거실콘센트"),
+		ELECTRIC02					("electric02",					"PowerOutlet",		"안방콘센트"),
+		ELECTRIC03					("electric03",					"PowerOutlet",		"서재콘센트"),
+		ELECTRIC04					("electric04",					"PowerOutlet",		"작은방콘센트"),
+		ELECTRIC05					("electric05",					"PowerOutlet",		"주방콘센트")
 		;
 		
 		
@@ -98,22 +125,24 @@ public final class THINGS_INFO {
 		//endpoint는 카카오 API와 연동될 기기 endpoint
 		// name 은 우리쪽에서 정의된 기기 명
 		// desc 는 기기 설명
-		LIGHT(1,"LIGHT", "Light", "조명스위치"),				
-		TEMPER(2, "TEMPER", "FloorHeater", "난방"),
-		ELECPLUG(3, "ELECTRIC", "PowerOutlet", "전기"),
-		GAS(4, "GAS", "GasValve", "가스밸브"),
-		ILGALSWITCH(5, "ILGALSWITCH", "ilgal", "일괄조명스위치"),
-		WALLPAD(6, "WALLPAD", "walpad", "월패드"),
-		VENTIL(7, "VENTIL", "AirVentilator", "환기시스템"),
-		NOTICE(8, "NOTICE", "InformationReporter", "공지사항"),
-		VOTE(9, "VOTE", "vote", "주민투표"),
-		PARKING(10, "PARKING", "parking", "주차위치"),
-		PARCEL(11, "PARCEL", "parcel", "택배도착"),
-		HEMS(12, "HEMS", "hems", "원격검침"),
-		CARIN(13, "CARIN", "carin", "주차관제(입차/출차)"),
-		ELEVATOR(14, "ELEVATOR", "ElevatorCaller", "엘리베이터"),
-		VISITOR(15, "VISITOR", "visitor", "방문자"),
-		EMERGENCY(16, "EMERGENCY", "emergency", "방범")
+		LIGHT			(1,	"LIGHT", 			"Light", 				"조명스위치"),				
+		TEMPER			(2, "TEMPER", 			"FloorHeater", 			"난방"),
+		ELECPLUG		(3, "ELECTRIC", 		"PowerOutlet", 			"전기"),
+		GAS				(4, "GAS", 				"GasValve", 			"가스밸브"),
+		ILGALSWITCH		(5, "ILGALSWITCH", 		"ilgal", 				"일괄조명스위치"),
+		WALLPAD			(6, "WALLPAD", 			"walpad", 				"월패드"),
+		VENTIL			(7, "VENTIL", 			"AirVentilator", 		"환기시스템"),
+		NOTICE			(8, "NOTICE", 			"InformationReporter", 	"공지사항"),
+		VOTE			(9, "VOTE", 			"vote", 				"주민투표"),
+		PARKING			(10, "PARKING", 		"parking", 				"주차위치"),
+		PARCEL			(11, "PARCEL", 			"parcel", 				"택배도착"),
+		HEMS			(12, "HEMS", 			"hems", 				"원격검침"),
+		CARIN			(13, "CARIN", 			"carin", 				"주차관제(입차/출차)"),
+		ELEVATOR		(14, "ELEVATORCALLER",	"ElevatorCaller", 		"엘리베이터"),
+		VISITOR			(15, "VISITOR", 		"visitor", 				"방문자"),
+		EMERGENCY		(16, "EMERGENCY", 		"emergency", 			"방범"),
+		LIGHTDIMMER		(17, "DIMMER", 	"LightDimmer", 			"디밍제어 조명"),
+		COLORLIGHTDIMMER(18, "COLORDIMMER", "ColorLightDimmer", 	"색온도 디밍제어 조명")
 		;
 		
 		private int endPoint;
@@ -165,9 +194,9 @@ public final class THINGS_INFO {
 		THINGS_INFO.THINGS things = getThingsType(modelId);
 		
 		return things == null ? false:true;
-	}
+	}     
 	
-	public static THINGS_INFO.DEVICE_DETAIL getDeviceInfo(String modelId){
+	public static THINGS_INFO.DEVICE_DETAIL getDeviceInfo(String modelId, String status){
 		THINGS_INFO.DEVICE_DETAIL[] list = THINGS_INFO.DEVICE_DETAIL.values();
 		
 		for(THINGS_INFO.DEVICE_DETAIL deviceDetail : list) {
@@ -175,25 +204,30 @@ public final class THINGS_INFO {
 				return deviceDetail;
 			}
 		}
-		
-		return null;
+		return null; 
 	}
 	
 	public static THINGS_INFO.THINGS getThingsType(String modelId){    
 		ThingsInfoRepository repo = (ThingsInfoRepository)BeanUtils.getBean("thingsInfoRepository");
 		THINGS_INFO.THINGS[] list = THINGS_INFO.THINGS.values();
 		
+		String[] splitModelId = modelId.split("_");
+		
 		for(THINGS_INFO.THINGS things:list) {
-			if(modelId.toLowerCase().contains(things.getThingsName().toLowerCase())) {
+//			if(modelId.toLowerCase().contains(things.getThingsName().toLowerCase())) {
+//				return things;
+//			}
+			if(splitModelId[0].equalsIgnoreCase(things.getThingsName()) || splitModelId[0].contains(things.getThingsName().toLowerCase())) {
+				System.out.println(splitModelId[0] + "--" + things.getThingsName());
 				return things;
 			}
 		}
-		
+		System.out.println("[ERROR] - " + modelId + " --> NULL");
 		return null;
 	}
 	
 	public static boolean isAvailableThings(String modelId) {
-		return Arrays.asList("livinglight", "light", "temper", "ventil", "gas").contains(modelId);
+		return Arrays.asList("livinglight", "light", "temper", "ventil", "gas", "electric").contains(modelId);
 	}
 	
 }

+ 2 - 1
src/main/java/com/icontrols/kakao/common/utils/UtilLib.java

@@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
 
 import com.icontrols.kakao.controller.MainController;
 
+
 public class UtilLib {
 	private static final Logger logger = LoggerFactory.getLogger(MainController.class);
 
@@ -22,7 +23,7 @@ public class UtilLib {
 		String deviceID = dong + "_" + ho + "_" + modelId + "_" + roomNum + "_" + cirNum;
 		AES256Util aes = new AES256Util();
 		String enc = aes.encrypt(deviceID);
-		logger.info(enc);
+//		logger.info(enc);
 		String random = UUID.randomUUID().toString().substring(0, 3);
 		result = random + enc;
 

+ 6 - 0
src/main/java/com/icontrols/kakao/common/utils/XmlUtil.java

@@ -15,4 +15,10 @@ public class XmlUtil {
 		
 		return _node.getAttributes().getNamedItem(_itemName).getTextContent();
 	}
+	
+	public static String getElemetTextValue(Node _node) {
+		if(_node == null) return null;
+		
+		return _node.getTextContent();
+	}
 }

+ 2 - 2
src/main/java/com/icontrols/kakao/config/DanziFilter.java

@@ -21,11 +21,11 @@ public class DanziFilter implements Filter{
 	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
 			throws IOException, ServletException {
 		
-		logger.info("[Request Access]");
+//		logger.info("[Request Access]");
 		
 		HttpServletResponse res = (HttpServletResponse) response;
 		
-		logger.debug("[Request Header Names] - " + res.getHeaderNames().toString());
+//		logger.debug("[Request Header Names] - " + res.getHeaderNames().toString());
 		chain.doFilter(request, response);
 	}
 

+ 3 - 3
src/main/java/com/icontrols/kakao/config/DanziTokenInterceptor.java

@@ -17,9 +17,9 @@ public class DanziTokenInterceptor implements HandlerInterceptor {
 	@Override
 	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
 			throws Exception {
-		logger.info("***");
-		logger.info("[Interceptor preHandle] - " + request.getHeader(HEADER_AUTH));
-		
+//		logger.info("***");
+//		logger.info("[Interceptor preHandle] - " + request.getHeader(HEADER_AUTH));
+//		
 		
 		return HandlerInterceptor.super.preHandle(request, response, handler);
 	}

+ 32 - 25
src/main/java/com/icontrols/kakao/controller/AuthController.java

@@ -39,30 +39,37 @@ public class AuthController {
 	@RequestMapping(value = "/kakao/test", method = RequestMethod.POST, consumes = "application/json")
 	public @ResponseBody Map<String, Object> test(@RequestBody Map<String, Object> body) throws Exception {
 		
-		ThingsInfo[] list = {new ThingsInfo("temper_5", "temper" , "802", "1103"),
-		 new ThingsInfo("light02_4", "light02" , "802", "1103"),
-		 new ThingsInfo("light03_3", "light03" , "802", "1103"),
-		 new ThingsInfo("temper_4", "temper" , "802", "1103"),    
-		 new ThingsInfo("light01_4", "light01" , "802", "1103"),        
-		 new ThingsInfo("light02_3", "light02" , "802", "1103"),        
-		 new ThingsInfo("light03_2", "light03" , "802", "1103"),        
-		 new ThingsInfo("temper_3", "temper" , "802", "1103"),        
-		 new ThingsInfo("ventil_1", "ventil" , "802", "1103"),   
-		 new ThingsInfo("temper_2", "temper" , "802", "1103"),   
-		 new ThingsInfo("temper_1", "temper" , "802", "1103"),   
-		 new ThingsInfo("light01_1", "light01" , "802", "1103"),   
-		 new ThingsInfo("light01_3", "light01" , "802", "1103"),   
-		 new ThingsInfo("light02_2", "light02" , "802", "1103"),   
-		 new ThingsInfo("light03_1", "light03" , "802", "1103"),   
-		 new ThingsInfo("livinglight_1", "livinglight" , "802", "1103"),       
-		 new ThingsInfo("light01_2", "light01" , "802", "1103"),       
-		 new ThingsInfo("light02_1", "light02" , "802", "1103"),       
-		 new ThingsInfo("gas_1", "gas" , "802", "1103"),       
-		 new ThingsInfo("livinglight_2", "livinglight" , "802", "1103"),       
-		 new ThingsInfo("livinglight_3", "livinglight" , "802", "1103"),       
-		 new ThingsInfo("livinglight_4", "livinglight" , "802", "1103"),       
-		 new ThingsInfo("livinglight_5", "livinglight" , "802", "1103"),
-		 new ThingsInfo("ElevatorCaller", "elevator" , "802", "1103")};
+		ThingsInfo[] list = {
+				new ThingsInfo("temper_5", "temper" , "802", "2504"),
+		 new ThingsInfo("light02_4", "light02" , "802", "2504"),
+		 new ThingsInfo("light03_3", "light03" , "802", "2504"),
+		 new ThingsInfo("temper_4", "temper" , "802", "2504"),    
+		 new ThingsInfo("light01_4", "light01" , "802", "2504"),        
+		 new ThingsInfo("light02_3", "light02" , "802", "2504"),        
+		 new ThingsInfo("light03_2", "light03" , "802", "2504"),        
+		 new ThingsInfo("temper_3", "temper" , "802", "2504"),        
+		 new ThingsInfo("ventil_1", "ventil" , "802", "2504"),   
+		 new ThingsInfo("temper_2", "temper" , "802", "2504"),   
+		 new ThingsInfo("temper_1", "temper" , "802", "2504"),   
+		 new ThingsInfo("light01_1", "light01" , "802", "2504"),   
+		 new ThingsInfo("light01_3", "light01" , "802", "2504"),   
+		 new ThingsInfo("light02_2", "light02" , "802", "2504"),   
+		 new ThingsInfo("light03_1", "light03" , "802", "2504"),   
+		 new ThingsInfo("colorDimming_livinglight_5", "livinglight" , "802", "2504"),       
+		 new ThingsInfo("light01_2", "light01" , "802", "2504"),       
+		 new ThingsInfo("light02_1", "light02" , "802", "2504"),       
+		 new ThingsInfo("gas_1", "gas" , "802", "2504"),      
+		 new ThingsInfo("colorDimming_livinglight_1", "livinglight" , "802", "2504"),       
+		 new ThingsInfo("colorDimming_livinglight_2", "livinglight" , "802", "2504"),       
+		 new ThingsInfo("colorDimming_livinglight_3", "livinglight" , "802", "2504"),       
+		 new ThingsInfo("colorDimming_livinglight_4", "livinglight" , "802", "2504"),
+		 new ThingsInfo("ElevatorCaller", "elevator" , "802", "2504"),
+		 new ThingsInfo("electric01", "electric" , "802", "2504"),       
+		 new ThingsInfo("electric02", "electric" , "802", "2504"),       
+		 new ThingsInfo("electric03", "electric" , "802", "2504"),       
+		 new ThingsInfo("electric04", "electric" , "802", "2504"),
+		 new ThingsInfo("electric05", "electric" , "802", "2504")
+		 };
 		
 		
 		for(ThingsInfo info:list) {
@@ -70,7 +77,7 @@ public class AuthController {
 		}
 		
 		
-		logger.info("kakao test --<>>>>>");
+		logger.info("kakao test --<>>>>> --> " + thingsRepo.count());
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		
 		

+ 14 - 16
src/main/java/com/icontrols/kakao/controller/KakaoDanziController.java

@@ -49,22 +49,20 @@ public class KakaoDanziController {
 														HttpServletResponse response, 
 														HttpServletRequest request
 														) throws Exception{
-		
-		
-		try {
-			String requestId = (String)params.get("id");
-			String requestType = (String) params.get("type");
-			String authorization = (String) params.get("authorization");
-			String body = params.containsKey("body")?params.get("body").toString():"";
-			
-			if(body.length() > 255) body = body.substring(0, 255);
-			
-			AccessLog log = new AccessLog(requestId, authorization, requestType, body);
-			accessLogRepository.save(log);
-		}catch(Exception e) {
-			logger.error("log 저장 실패 " + e.getMessage());
-			e.printStackTrace();
-		}
+//		try {
+//			String requestId = (String)params.get("id");
+//			String requestType = (String) params.get("type");
+//			String authorization = (String) params.get("authorization");
+//			String body = params.containsKey("body")?params.get("body").toString():"";
+//			
+//			if(body.length() > 255) body = body.substring(0, 255);
+//			
+//			AccessLog log = new AccessLog(requestId, authorization, requestType, body);
+//			accessLogRepository.save(log);
+//		}catch(Exception e) {
+//			logger.error("log 저장 실패 " + e.getMessage());
+//			e.printStackTrace();
+//		}
 		
 		logger.debug("[REQUEST] - "+ params.toString());
 		

+ 33 - 33
src/main/java/com/icontrols/kakao/controller/MainController.java

@@ -49,43 +49,43 @@ public class MainController {
 														HttpServletResponse response, 
 														HttpServletRequest request) throws Exception {
 		
-		logger.debug("kakaoMsgHandler is null" + kakaoMsgHandler);
+//		logger.debug("kakaoMsgHandler is null" + kakaoMsgHandler);
 		logger.info("===================================================================================");
 		logger.info("==========================================이벤트 수신=================================");
 		logger.info("===================================================================================");
-		logger.info("body :" + params.toString());
-
-		Map<String,Object> retMap = new HashMap<String, Object>();
-		
-		retMap.put(KEY_INFO.HTTP_KEY_ID, params.get(KEY_INFO.HTTP_KEY_ID));
-		retMap.put(KEY_INFO.HTTP_KEY_TYPE, params.get(KEY_INFO.HTTP_KEY_TYPE));
-		retMap.put(KEY_INFO.HTTP_KEY_VERSION, params.get(KEY_INFO.HTTP_KEY_VERSION));
-		
-		String jsonString = "{\"name\":\"mkyong\", \"age\":29}";
-		Map<String, Object> testmap = CommonUtil.jsonToMap(jsonString);
-		
-		logger.debug("--------->>>>>  "+testmap.get("name").toString());
+		logger.info("body :" + header);
 
-		retMap.putAll(KakaoMsgHandler.getDeviceCapabilities("light"));
-		
-		String originAuth = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
-		String encode = Base64.getEncoder().encodeToString(originAuth.getBytes());
-		
-		logger.debug("____________" + encode);
-		
-		String decode = new String(Base64.getDecoder().decode(encode));
-		logger.debug("decode --> " + decode);
-		
-		originAuth = SERVERINFO.KAKAO_HEADER_CLIENT_ID+":"+SERVERINFO.KAKAO_HEADER_CLIENT_SECRET;
-		encode = Base64.getEncoder().encodeToString(originAuth.getBytes());
-		
-		logger.debug("_____HEADER_______" + encode);
-		
-		decode = new String(Base64.getDecoder().decode(encode));
-		logger.debug("decode --> " + decode);
-		
-		
-		return retMap;
+//		Map<String,Object> retMap = new HashMap<String, Object>();
+//		
+//		retMap.put(KEY_INFO.HTTP_KEY_ID, params.get(KEY_INFO.HTTP_KEY_ID));
+//		retMap.put(KEY_INFO.HTTP_KEY_TYPE, params.get(KEY_INFO.HTTP_KEY_TYPE));
+//		retMap.put(KEY_INFO.HTTP_KEY_VERSION, params.get(KEY_INFO.HTTP_KEY_VERSION));
+//		
+//		String jsonString = "{\"name\":\"mkyong\", \"age\":29}";
+//		Map<String, Object> testmap = CommonUtil.jsonToMap(jsonString);
+//		
+//		logger.debug("--------->>>>>  "+testmap.get("name").toString());
+//
+//		retMap.putAll(KakaoMsgHandler.getDeviceCapabilities("light",""));
+//		
+//		String originAuth = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
+//		String encode = Base64.getEncoder().encodeToString(originAuth.getBytes());
+//		
+//		logger.debug("____________" + encode);
+//		
+//		String decode = new String(Base64.getDecoder().decode(encode));
+//		logger.debug("decode --> " + decode);
+//		
+//		originAuth = SERVERINFO.KAKAO_HEADER_CLIENT_ID+":"+SERVERINFO.KAKAO_HEADER_CLIENT_SECRET;
+//		encode = Base64.getEncoder().encodeToString(originAuth.getBytes());
+//		
+//		logger.debug("_____HEADER_______" + encode);
+//		
+//		decode = new String(Base64.getDecoder().decode(encode));
+//		logger.debug("decode --> " + decode);
+//		
+//		
+		return null;
 	}
 	
 	@RequestMapping(value = "/events", method = RequestMethod.POST, consumes = "application/json")

+ 1 - 0
src/main/java/com/icontrols/kakao/repo/DonghoInfoRepository.java

@@ -7,6 +7,7 @@ import org.springframework.data.repository.CrudRepository;
 import com.icontrols.kakao.entity.DonghoInfo;
 
 public interface DonghoInfoRepository extends CrudRepository<DonghoInfo, Long> {
+	int countByDongAndHoAndDeleteFlag(String dong, String ho, String deleteFlag);
 	List<DonghoInfo> findByDongAndHo(String dong, String ho);
 	List<DonghoInfo> findByKakaoAccessTokenAndKakaoRefreshToken(String kakaoAccessToken, String kakaoRefreshToken);
 }

+ 1 - 0
src/main/java/com/icontrols/kakao/service/AuthService.java

@@ -5,4 +5,5 @@ import java.util.Map;
 public interface AuthService {
 	public Map<String, Object> authProcess(Map<String, Object> param) throws Exception;
 	public Map<String, Object> subscriptionProcess(Map<String, Object> param) throws Exception;
+	public Map<String, Object> remoteRegisterNewDevice(Map<String, Object> param) throws Exception;
 }

+ 5 - 0
src/main/java/com/icontrols/kakao/service/impl/AuthServiceImpl.java

@@ -26,4 +26,9 @@ public class AuthServiceImpl implements AuthService {
 		return kMsgHandler.subscriptionProcess(param);
 	}
 
+	@Override
+	public Map<String, Object> remoteRegisterNewDevice(Map<String, Object> param) throws Exception {
+		// TODO Auto-generated method stub
+		return kMsgHandler.remoteRegisterNewDevice(param);
+	}
 }

+ 39 - 25
src/main/java/com/icontrols/kakao/service/impl/KakaoExtensionServiceImpl.java

@@ -21,6 +21,7 @@ import com.icontrols.kakao.entity.DonghoInfo;
 import com.icontrols.kakao.entity.ThingsInfo;
 import com.icontrols.kakao.repo.DonghoInfoRepository;
 import com.icontrols.kakao.repo.ThingsInfoRepository;
+import com.icontrols.kakao.service.AuthService;
 import com.icontrols.kakao.service.KakaoExtensionService;
 import com.icontrols.kakao.socket.wallpad.KakaoMsgHandler;
 import com.icontrols.kakao.socket.wallpad.WallpadMsgSender;
@@ -39,6 +40,9 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 	@Resource(name="wallpadMsgSender")
 	WallpadMsgSender wallpadMsgSender;
 	
+	@Autowired
+	AuthService authService;
+	
 	@Autowired
 	DonghoInfoRepository donghoRepository;
 	
@@ -48,11 +52,8 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 	@Override
 	public Map<String, Object> request_grantAuthorization(Map<String, Object> param) throws Exception {
 		String dong_ho = JWTUtils2.getHomeIdFromToken((String)param.get(KEY_INFO.HTTP_KEY_AUTHORIZATION));
-//		int dong = Integer.parseInt(dong_ho.split("/")[0]);
-//		int ho = Integer.parseInt(dong_ho.split("/")[1]);
-		
-		int dong = 802;
-		int ho = 1103;
+		int dong = Integer.parseInt(dong_ho.split("/")[0]);
+		int ho = Integer.parseInt(dong_ho.split("/")[1]);
 		
 		Map<String, Object> body = (HashMap)param.get(KEY_INFO.HTTP_KEY_BODY);
 		
@@ -71,15 +72,28 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 																									(String) body.get(KEY_INFO.BODY_KEY_ACCESS_TOKEN), 
 																									(String) body.get(KEY_INFO.BODY_KEY_REFRESH_TOKEN)
 																								);
-			
 			if(dList.size() > 0)
 				donghoInfo.setId(dList.get(0).getId());
 
-			donghoRepository.save(donghoInfo);
+			
 			
 			logger.debug("dongho info saved complete " );
 			logger.debug(donghoInfo.toString());
 			
+			Map<String, Object> subsMap = new HashMap<String, Object>();
+			
+			subsMap.put("type", "subs");
+			subsMap.put("dong", dong_ho.split("/")[0]);
+			subsMap.put("ho", dong_ho.split("/")[1]);
+			subsMap.put("devNum", "1");
+			subsMap.put("company", "kakao");
+			
+			authService.subscriptionProcess(subsMap);
+			
+			
+			authService.remoteRegisterNewDevice(subsMap);
+			
+			donghoRepository.save(donghoInfo);
 		}catch(Exception e) {
 			logger.error("[Auth Database Insert Error]");
 			e.printStackTrace();
@@ -94,11 +108,8 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 	@Override
 	public Map<String, Object> request_discover(Map<String, Object> param) throws Exception{
 		String dong_ho = JWTUtils2.getHomeIdFromToken((String)param.get(KEY_INFO.HTTP_KEY_AUTHORIZATION));
-//		int dong = Integer.parseInt(dong_ho.split("/")[0]);
-//		int ho = Integer.parseInt(dong_ho.split("/")[1]);
-		
-		int dong = 802;
-		int ho = 1103;
+		int dong = Integer.parseInt(dong_ho.split("/")[0]);
+		int ho = Integer.parseInt(dong_ho.split("/")[1]);
 		
 		Map<String, Object> listMap = kMsgHandler.getDevicesStatusList(dong, ho);
 		param.putAll(listMap);
@@ -110,21 +121,19 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 	@Override
 	public Map<String, Object> request_queryState(Map<String, Object> param) throws Exception {
 		String dong_ho = JWTUtils2.getHomeIdFromToken((String)param.get(KEY_INFO.HTTP_KEY_AUTHORIZATION));
-//		int dong = Integer.parseInt(dong_ho.split("/")[0]);
-//		int ho = Integer.parseInt(dong_ho.split("/")[1]);
-		
-		int dong = 802;
-		int ho = 1103;
+		int dong = Integer.parseInt(dong_ho.split("/")[0]);
+		int ho = Integer.parseInt(dong_ho.split("/")[1]);
 		
 		Map <String, Object> body = (HashMap)param.get(KEY_INFO.HTTP_KEY_BODY);
 		
 		List<String> endpointIds = body.containsKey(KEY_INFO.BODY_KEY_ENDPOINT_IDS)?(ArrayList)body.get(KEY_INFO.BODY_KEY_ENDPOINT_IDS):null;
 		List<String> unreachableIds = new ArrayList<String>();
-		Map<String, Object> allDeviceMap = (Map<String, Object>) kMsgHandler.getDevicesStatusList(dong, ho).get(KEY_INFO.HTTP_KEY_BODY);
+		Map<String, Object> allDeviceMap = null;
 		
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		
-		logger.debug(allDeviceMap.toString());
+		logger.info("[QUERYSTATE] - " + endpointIds);
+		
 		try {
 			if(endpointIds == null) {
 				param.remove(KEY_INFO.HTTP_KEY_BODY);
@@ -137,6 +146,9 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 				return param;
 			}
 			
+			allDeviceMap = (Map<String, Object>) kMsgHandler.getDevicesStatusList(dong, ho).get(KEY_INFO.HTTP_KEY_BODY);
+			logger.debug("[DEViCES] - " + allDeviceMap.toString());
+			
 			for(String endpointId:endpointIds) {
 				// 1. db 에서 해당 endpointId가 존재하는지 확인한다.
 				// 없으면 endpointId가 잘못된것 -203 에러를 뱉자.
@@ -190,11 +202,8 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 	@Override
 	public Map<String, Object> request_updateState(Map<String, Object> param) throws Exception {
 		String dong_ho = JWTUtils2.getHomeIdFromToken((String)param.get(KEY_INFO.HTTP_KEY_AUTHORIZATION));
-//		int dong = Integer.parseInt(dong_ho.split("/")[0]);
-//		int ho = Integer.parseInt(dong_ho.split("/")[1]);
-		
-		int dong = 802;
-		int ho = 1103;
+		int dong = Integer.parseInt(dong_ho.split("/")[0]);
+		int ho = Integer.parseInt(dong_ho.split("/")[1]);
 		
 		@SuppressWarnings("unchecked")
 		Map <String, Object> body = (HashMap<String, Object>)param.get(KEY_INFO.HTTP_KEY_BODY);
@@ -208,16 +217,21 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 		logger.debug("[UPDATE] - " + body.toString());
 		
 		List<ThingsInfo> thingsInfoList = thingsInfoRepository.findByDongAndHoAndEndpointId(Integer.toString(dong), Integer.toString(ho), endpointId);
+		
 		if(thingsInfoList == null || thingsInfoList.size() == 0) {
 			retMap = new HashMap<String, Object>();
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_NONEXIST));
 		}else {
 			retMap = kMsgHandler.sendDeviceAction(dong, ho, endpointId, capabilityName, desired);
 		}
-		
+		logger.debug("UPDATE-->>retMap : " + retMap.toString());
 		if(retMap.containsKey(KEY_INFO.HTTP_KEY_ERROR)) {
 			param.remove(KEY_INFO.HTTP_KEY_BODY);
 			param.putAll(retMap);
+		}else {
+			body.clear();
+			body.putAll(retMap);
+			param.put(KEY_INFO.HTTP_KEY_BODY, body);
 		}
 
 		return param;

+ 11 - 1
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoEventHandler.java

@@ -101,18 +101,28 @@ public class KakaoEventHandler {
 			
 			int code = (int) sendResult.get("result");
 			
+			DonghoInfoRepository repo = null;
 			switch(code) {
 			case KAKAO_RESULT.FAIL_INTERNAL:
 				break;
 			case KAKAO_RESULT.FAIL_INVALID_TOKEN: // 유효하지 않은 토큰, 연동 해제한 계정 토큰
 				logger.info("["+donghoInfo.getKakaoAccessToken()+"] - 유효하지 않은 토큰..삭제요청");
-				DonghoInfoRepository repo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
+				repo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
 				donghoInfo.setDeleteFlag("Y");
 				repo.save(donghoInfo);
 				
 				retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
 				retMap.put("message", "ID-["+donghoInfo.getId() + "]-FAIL_INVALID_TOKEN");
 				break;
+			case KAKAO_RESULT.FAIL_UNLINKEXTENSION_SERVICE: // 서비스를 해지한 경우
+				logger.info("["+donghoInfo.getKakaoAccessToken()+"] - 서비스 해제 토근..삭제요청");
+				repo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
+				donghoInfo.setDeleteFlag("Y");
+				repo.save(donghoInfo);
+				
+				retMap.put("result", KAKAO_RESULT.FAIL_UNLINKEXTENSION_SERVICE);
+				retMap.put("message", "ID-["+donghoInfo.getId() + "]-FAIL_UNLINKEXTENSION_SERVICE");
+				break;
 			case KAKAO_RESULT.FAIL_EXPIREDTOKEN:  // 만료된 토큰, 토큰 재발급 뒤 재시도.
 				// 재시도 할때는 따로 결과를 받지 않을려고.. 성공할때까지 계속 시도하는것도 비효율적.
 				logger.info("["+donghoInfo.getKakaoAccessToken()+"]-인증토큰 만료 토큰 갱신 요청");

+ 237 - 57
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoMsgHandler.java

@@ -43,10 +43,12 @@ import com.icontrols.kakao.common.KEY_INFO;
 import com.icontrols.kakao.common.SERVERINFO;
 import com.icontrols.kakao.common.THINGS_INFO;
 import com.icontrols.kakao.common.TYPE;
+import com.icontrols.kakao.common.THINGS_INFO.THINGS;
 import com.icontrols.kakao.common.TYPE.XML_LIGHT;
 import com.icontrols.kakao.common.utils.BeanUtils;
 import com.icontrols.kakao.common.utils.CommonUtil;
 import com.icontrols.kakao.common.utils.NodeUtil;
+import com.icontrols.kakao.common.utils.XmlUtil;
 import com.icontrols.kakao.config.AsyncConfig;
 import com.icontrols.kakao.entity.DonghoInfo;
 import com.icontrols.kakao.repo.DonghoInfoRepository;
@@ -80,7 +82,8 @@ public class KakaoMsgHandler {
 			String code = (String)param.get("code");
 			
 			String targetIP = IPGenerator.getIPFromDongHo(dong, ho);
-			String twinid = UUID.randomUUID().toString();
+//			String twinid = UUID.randomUUID().toString();
+			String twinid = "KAKAO"+dong+"_"+ho;
 			String alias = "Kakao";
 			StringBuffer sb = new StringBuffer();
 			
@@ -129,6 +132,37 @@ public class KakaoMsgHandler {
 		return retMap;
 	}
 	
+	public Map<String, Object> remoteRegisterNewDevice(Map<String, Object> param) { 
+Map<String, Object> retMap = new HashMap<String, Object>();
+		
+		try {
+			int dong = Integer.parseInt((String)param.get("dong"));
+			int ho = Integer.parseInt((String)param.get("ho"));
+			String code = (String)param.get("code");
+			
+			String targetIP = IPGenerator.getIPFromDongHo(dong, ho);
+			String twinid = "KAKAO_"+dong+"_"+ho;
+			String alias = "KAKAO HOME";
+			StringBuffer sb = new StringBuffer();
+			
+			sb.append(XMLGenerator.MakeXMLHeaderForSUBS("remote_register_new_device"))
+			.append("      <home_info dong=\"").append(dong).append("\" ho=\"").append(ho).append("\" ip=\"").append(targetIP).append("\" type=\"main\"/>\r\n")
+			.append("      <device_info alias=\"").append(alias).append("\" twinid=\"").append(twinid).append("\"  />\r\n")
+			.append(XMLGenerator.MakeXMLTail());
+			
+			logger.info(sb.toString());
+			
+			SSLClient.sendToWallpad(targetIP, sb.toString());
+			
+			retMap.put("result", ERROR_INFO.CODE.SUCCESS.getContents());
+			retMap.put("resultCode", ERROR_INFO.CODE.SUCCESS.getmIdx());
+		}catch(Exception e) {
+			retMap.put("result", ERROR_INFO.CODE.FAIL_999.getContents());
+			retMap.put("resultCode", ERROR_INFO.CODE.FAIL_999.getmIdx());
+			e.printStackTrace();
+		}
+		return retMap;
+	}
 	/**
 	 * 월패드와 연결된 기기들의 전체 상태를 월패드에 요청하고 응답 받는다.
 	 * 지원 기기가 추가되면 해당 부분은 수정이 필요하다. 
@@ -137,6 +171,7 @@ public class KakaoMsgHandler {
 	 * @param ho
 	 * @return
 	 */
+	
 	public Map<String, Object> getDevicesStatusList(int dong, int ho) {
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		Map<String, Object> body = new HashMap<String, Object>();
@@ -153,7 +188,7 @@ public class KakaoMsgHandler {
 			
 			XPath xpath = XPathFactory.newInstance().newXPath();
 			Node iMap = (Node)xpath.evaluate("//imap/service", doc, XPathConstants.NODE);
-			String xmlResult = iMap.getAttributes().getNamedItem("result").getTextContent();
+			String xmlResult = XmlUtil.getAttributeWithItem(iMap, "result");
 			
 			logger.debug("[KakaoMsgHandler - getDeviceList] - xmlResult -> " + xmlResult);
 			
@@ -165,33 +200,42 @@ public class KakaoMsgHandler {
 			
 			// 월패드와 연결된 상위 THINGS 갯수 확인
 			Node dCount =  null;
-	        
 			NodeList devList = (NodeList)xpath.evaluate("//imap/service/devinfo", doc, XPathConstants.NODESET);
 			
-			
 			NodeUtil.asList(devList)
 					.stream()
-					.filter(pNode -> THINGS_INFO.isAvailableThings(pNode.getAttributes().getNamedItem("name").getTextContent()))
+					.filter(pNode -> THINGS_INFO.isAvailableThings(XmlUtil.getAttributeWithItem(pNode, "name")))
 					.forEach(pNode -> {
-						String tmpModelId = pNode.getAttributes().getNamedItem("name").getTextContent();
-						int childCount = Integer.parseInt(pNode.getAttributes().getNamedItem("value").getTextContent());
+						String tmpModelId = XmlUtil.getAttributeWithItem(pNode, "name");
+						int childCount = Integer.parseInt(XmlUtil.getAttributeWithItem(pNode, "value"));
 						
 						List<Map<String, Object>> childNodeInfoList = null;
-						
+						logger.debug("tmpModelID --> " + tmpModelId);
 						try {
 							// subdevinfo 를 가지고 있는 THINGS일 경우는 subdevinfo 들을 다시 구해야 한다.
 							// 예를들어 light는 light01 ~ 05 등의 subdevinfo를 가진다.
-							if(tmpModelId.equalsIgnoreCase("light")) {
+
+							// livinglight와 light는 -> dimmer와 colorTemp를 조절이 가능한 조명이 포함될 수 있다.
+							// 전등의 경우 월패드에서는 크게 livinglight 또는 light 로 나뉘고 속성은 같은반변 
+							// 카카오에서는 light, LightDimmer, ColorLightDimmer 세가지로 나뉜다.
+							// 월패드의 status는 (전원)/(디밍값)/(색상온도값) 으로 구성되며 
+							// 전원을 제외하고 각 지원하지 않는 기능은 null로 전달된다. 
+							// LightDimmer는 월패드에서 status가 on/40/null 로  status가 구성되고
+							// ColorLightDimmer는 월패드에서 status가 on/40/10 의 형태 또는 status가 on/null/10 의형태로 구성된다. 
+							// status의 구성요소에 맞게 capability가 구성되어야 한다. 
+							
+							
+							if(tmpModelId.equalsIgnoreCase("light") || tmpModelId.equalsIgnoreCase("electric")) {
 								for(int j=1; j <= childCount; j++) {
 									String childName = j < 10 ? tmpModelId+"0"+j : tmpModelId+j;
 									Node childNode = (Node)xpath.evaluate("//imap/service/devinfo/*[@name='"+ childName +"']", doc, XPathConstants.NODE);
-									
-									childCount = Integer.parseInt(childNode.getAttributes().getNamedItem("value").getTextContent());
+									logger.debug("childName = " + childName);
+									childCount = Integer.parseInt(XmlUtil.getAttributeWithItem(childNode, "value"));
 									
 									NodeList childList = (NodeList)xpath.evaluate("//imap/service/devinfo/subdevinfo/*[@name='"+ childName +"']", doc, XPathConstants.NODESET);
 									
 									childNodeInfoList = getChildDeviceInfo(childCount, childList);
-									
+									logger.debug("child-->>" + childNodeInfoList.toString());
 									if(childNodeInfoList != null)
 										childNodeInfoList.forEach(tMap -> { body.putAll(tMap); });
 								}
@@ -200,20 +244,24 @@ public class KakaoMsgHandler {
 								
 								childNodeInfoList = getChildDeviceInfo(childCount, childList);
 								
+								logger.debug("child-->>" + childNodeInfoList.toString());
+								
 								if(childNodeInfoList != null)
 									childNodeInfoList.forEach(tMap -> { body.putAll(tMap); });
 							}
 						}catch(Exception e) {
 							retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
 							logger.error("[ERROR] at stream - " + e.getMessage());
+							e.printStackTrace();
 						}
 					});
 			
 			// elevator는 하드코딩.
 			// elevator가 존재해야 카카오홈 앱에서 엘리베이터를 제어할 수 있다.
 			Map<String, Object> eleMap = new HashMap<String, Object>();
+			
 			eleMap.put("displayType", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
-			eleMap.putAll(getDeviceCapabilities(THINGS_INFO.THINGS.ELEVATOR.getThingsName()));
+			eleMap.putAll(getDeviceCapabilities(THINGS_INFO.THINGS.ELEVATOR.getThingsName(), null));
 			eleMap.put("endpointId", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
 			eleMap.put("name", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
 			eleMap.put("state", new HashMap<String, Object>());
@@ -294,15 +342,18 @@ public class KakaoMsgHandler {
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		
 		String[] tmpSplit = endpointId.split("_");
-		String modelId = tmpSplit[0];
+		String modelId = (tmpSplit[0].equals("dimmer") || tmpSplit[0].equals("colorDimmer"))?tmpSplit[1]:tmpSplit[0];
 		
 		if(tmpSplit.length == 1 && !modelId.equals(THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName())) {
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_NONEXIST));
 			return retMap;
 		}
 		
-		int devNum = modelId.equals(THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName())?1:Integer.parseInt(tmpSplit[1]);
+		int devNum = 1;
 		
+		if(tmpSplit[0].equals("dimmer") || tmpSplit[0].equals("colorDimmer")) devNum = Integer.parseInt(tmpSplit[2]);
+		else if(modelId.equals(THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName())) devNum = 1;
+		else devNum = Integer.parseInt(tmpSplit[1]);
 		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(endpointId);
 		
 		if(things == null) {
@@ -310,7 +361,8 @@ public class KakaoMsgHandler {
 			logger.error("[ERROR] - things null ==> INVALID REQ");
 			return retMap;
 		}
-		String action = KakaoMsgHandler.setDeviceActionStr(modelId, actionName, desired);
+		
+		String action = KakaoMsgHandler.setDeviceActionStr(endpointId, modelId, actionName, desired);
 		
 		if(action.length() == 0) {
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INVALID_REQ));
@@ -346,7 +398,7 @@ public class KakaoMsgHandler {
 		XPath xpath = XPathFactory.newInstance().newXPath();
 		try {
 			Node iMap = (Node) xpath.evaluate("//imap/service", doc, XPathConstants.NODE);
-			String xmlResult = iMap.getAttributes().getNamedItem("result").getTextContent();
+			String xmlResult = XmlUtil.getAttributeWithItem(iMap, "result");
 			
 			if(!xmlResult.equalsIgnoreCase("ok")) {
 				retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INVALID_REQ)); 
@@ -363,6 +415,8 @@ public class KakaoMsgHandler {
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
 			e.printStackTrace();
 		}
+		
+		logger.debug("[UPDATE RESULT] - " + retMap.toString());
 		return retMap;
 	}
 	
@@ -395,7 +449,7 @@ public class KakaoMsgHandler {
 	 * @param modelId
 	 * @return
 	 */
-	public static Map<String, Object> getDeviceCapabilities(String modelId){
+	public static Map<String, Object> getDeviceCapabilities(String modelId, String status){
 		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(modelId);
 		
 		String jsonString = "";
@@ -404,6 +458,17 @@ public class KakaoMsgHandler {
 		case THINGS_INFO.THINGS_LIGHT:
 			jsonString = THINGS_INFO.THINGS_CAPABILITY.LIGHT.getCapJsonStr();
 			break;
+		case THINGS_INFO.THINGS_LIGHT_DIMMER:
+			jsonString = THINGS_INFO.THINGS_CAPABILITY.LIGHT_DIMMER.getCapJsonStr();
+			break;
+			
+		case THINGS_INFO.THINGS_COLOR_LIGHT_DIMMER:
+			String[] splitStr = status.split("/");
+			if(splitStr[1].equals("null"))
+				jsonString = THINGS_INFO.THINGS_CAPABILITY.COLOR_LIGHT.getCapJsonStr();
+			else
+				jsonString = THINGS_INFO.THINGS_CAPABILITY.COLOR_LIGHT_DIMMER.getCapJsonStr();
+			break;
 			
 		case THINGS_INFO.THINGS_TEMPER:
 			jsonString = THINGS_INFO.THINGS_CAPABILITY.TEMPER.getCapJsonStr();
@@ -416,13 +481,15 @@ public class KakaoMsgHandler {
 		case THINGS_INFO.THINGS_VENTIL:
 			jsonString = THINGS_INFO.THINGS_CAPABILITY.VENTIL.getCapJsonStr();
 			break;
+			
 		case THINGS_INFO.THINGS_ELEVATOR:
 			jsonString = THINGS_INFO.THINGS_CAPABILITY.ELEVATOR.getCapJsonStr();
 			break;
+			
 		case THINGS_INFO.THINGS_ELECPLUG:
+			jsonString = THINGS_INFO.THINGS_CAPABILITY.ELECTRIC.getCapJsonStr();
 			break;
 		}
-		
 		Map<String, Object> capabilities = CommonUtil.jsonToMap(jsonString);
 		
 		return capabilities;
@@ -437,35 +504,59 @@ public class KakaoMsgHandler {
 	public List<Map<String, Object>> getChildDeviceInfo(int childCount, NodeList childList){
 		List<Map<String, Object>> deviceList = new ArrayList<>();
 		try {
-			NodeUtil.asList(childList).forEach(cNode -> {
-				Map<String, Object> deviceMap = new HashMap<>();
-				
-				String cNodeName = cNode.getAttributes().getNamedItem("name").getTextContent();
-				String cNodeDevNum = cNode.getAttributes().getNamedItem("dev_num").getTextContent();
-				String status = cNode.getTextContent();
-				String endpointId = cNodeName+"_"+cNodeDevNum;
-				
-				String tmpModelId = cNodeName.equals("temper")?endpointId:cNodeName;
-				
-				THINGS_INFO.DEVICE_DETAIL detailDev = THINGS_INFO.getDeviceInfo(tmpModelId);
-				
-				Map<String, Object> deviceInfo =  new HashMap<String, Object>();
-				
-				deviceInfo.put(KEY_INFO.BODY_KEY_ENDPOINT_ID, endpointId);
-	    		deviceInfo.put(KEY_INFO.BODY_KEY_NAME, detailDev.getDisplayName()+cNodeDevNum);
-	    		deviceInfo.put(KEY_INFO.BODY_KEY_DISPLAY_TYPE, detailDev.getDisplayType());
-	    		
-	    		deviceInfo.putAll(getDeviceCapabilities(endpointId));
-	    		deviceInfo.put(KEY_INFO.BODY_KEY_STATE, setDeviceState(endpointId, status));
-	    		
-	    		deviceMap.put(endpointId, deviceInfo);
-	    		
-	    		deviceList.add(deviceMap);
-			});			
+			NodeUtil.asList(childList)
+				.stream()
+				.filter(cNode -> cNode != null)
+				.forEach(cNode -> {
+					try {
+						Map<String, Object> deviceMap = new HashMap<>();
+						String cNodeName = XmlUtil.getAttributeWithItem(cNode, "name");
+						String cNodeDevNum = XmlUtil.getAttributeWithItem(cNode, "dev_num");
+						String status = XmlUtil.getElemetTextValue(cNode);
+						String endpointId = cNodeName+"_"+cNodeDevNum;
+						
+						if(cNodeName.contains("light")) {
+							String[] strSplit = status.split("/");
+							// split 이 안됐다면 on off만 되는 예전 방식으로 전등 상태를 받았다는 뜻.
+							if(strSplit.length > 1) {
+								if(!strSplit[1].equals("null") && strSplit[2].equals("null")) {
+									endpointId = "dimmer_"+endpointId;
+									cNodeName = "dimmer_" + cNodeName;
+								}
+								else if(!strSplit[2].equals("null")) {
+									endpointId = "colorDimmer_"+endpointId;
+									cNodeName = "colorDimmer_"+cNodeName;
+								}
+							}
+						}
+						
+			 			String tmpModelId = cNodeName.equals("temper")?endpointId:cNodeName;
+						logger.debug("tmpModelId = " + tmpModelId + " || endpointID = " + endpointId);
+			 			
+						
+						THINGS_INFO.DEVICE_DETAIL detailDev = THINGS_INFO.getDeviceInfo(tmpModelId, status);
+						
+						Map<String, Object> deviceInfo =  new HashMap<String, Object>();
+						
+						deviceInfo.put(KEY_INFO.BODY_KEY_ENDPOINT_ID, endpointId);
+			    		deviceInfo.put(KEY_INFO.BODY_KEY_NAME, detailDev.getDisplayName()+cNodeDevNum);
+			    		deviceInfo.put(KEY_INFO.BODY_KEY_DISPLAY_TYPE, detailDev.getDisplayType());
+			    		
+			    		
+			    		deviceInfo.putAll(getDeviceCapabilities(endpointId, status));
+			    		deviceInfo.put(KEY_INFO.BODY_KEY_STATE, setDeviceState(endpointId, status));
+			    		
+			    		deviceMap.put(endpointId, deviceInfo);
+			    		deviceList.add(deviceMap);
+			    		
+					}catch(Exception e) {
+						e.printStackTrace();
+					}
+					
+				});			
 		}catch(Exception e) {
 			return null;
 		}
-		
 		return deviceList;
 	}
 	
@@ -481,22 +572,31 @@ public class KakaoMsgHandler {
 				return null;
 			}
 			
-			String cNodeName = cNode.getAttributes().getNamedItem("name").getTextContent();
-			String cNodeDevNum = cNode.getAttributes().getNamedItem("dev_num").getTextContent();
-			String status = cNode.getTextContent();
+			String cNodeName = XmlUtil.getAttributeWithItem(cNode, "name");
+			String cNodeDevNum = XmlUtil.getAttributeWithItem(cNode, "dev_num");
+			String status = XmlUtil.getElemetTextValue(cNode);
 			String endpointId = cNodeName+"_"+cNodeDevNum;
 			
-			String tmpModelId = cNodeName.equals("temper")?endpointId:cNodeName;
+ 			String tmpModelId = cNodeName.equals("temper")?endpointId:cNodeName;
 			
-			THINGS_INFO.DEVICE_DETAIL detailDev = THINGS_INFO.getDeviceInfo(tmpModelId);
+			THINGS_INFO.DEVICE_DETAIL detailDev = THINGS_INFO.getDeviceInfo(tmpModelId, status);
 			
 			Map<String, Object> deviceInfo =  new HashMap<String, Object>();
 			
+			THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(cNodeName);
+			
+			if(things.getEndPoint() == THINGS_INFO.THINGS_COLOR_LIGHT_DIMMER)
+				endpointId = "colorDimming_"+endpointId;
+			
+			if(things.getEndPoint() == THINGS_INFO.THINGS_LIGHT_DIMMER) 
+				endpointId = "dimming_"+endpointId;
+			
+			
 			deviceInfo.put(KEY_INFO.BODY_KEY_ENDPOINT_ID, endpointId);
     		deviceInfo.put(KEY_INFO.BODY_KEY_NAME, detailDev.getDisplayName()+cNodeDevNum);
     		deviceInfo.put(KEY_INFO.BODY_KEY_DISPLAY_TYPE, detailDev.getDisplayType());
     		
-    		deviceInfo.putAll(getDeviceCapabilities(endpointId));
+    		deviceInfo.putAll(getDeviceCapabilities(endpointId, status));
     		deviceInfo.put(KEY_INFO.BODY_KEY_STATE, setDeviceState(endpointId, status));
     		
     		deviceMap.put(endpointId, deviceInfo);
@@ -514,32 +614,82 @@ public class KakaoMsgHandler {
 	 * @return
 	 */
 	
-	public static String setDeviceActionStr(String modelId, String capability, Map<String, Object> desired) {
+	public static String setDeviceActionStr(String endPointId, String modelId, String capability, Map<String, Object> desired) {
 		StringBuffer sb = new StringBuffer();
 		
-		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(modelId);
+		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(endPointId);
 		
 		logger.debug("[setDeiceActionStr] - modelId = " + modelId + " || capability = " + capability + " || things endpoint = " + things.getEndPoint());
+		logger.debug("ACTION STATUS --> " + desired.toString());
 		try {
+			int brightness = 1;
+			int colorTemer = 1;
 			switch(things.getEndPoint()) {
+				
 			case THINGS_INFO.THINGS_LIGHT:
 				if(capability.equals("Power") && desired.containsKey("power")) {
 					String tmpState = (String)desired.get("power");
 					if(tmpState.equals("on") || tmpState.equals("off")) sb.append(tmpState);
 				}
 				
+				break;
+			case THINGS_INFO.THINGS_LIGHT_DIMMER:
+				
+				if(capability.equals("Power") && desired.containsKey("power")) {
+					String tmpState = (String)desired.get("power");
+					if(tmpState.equals("on") || tmpState.equals("off")) {
+						sb.append(tmpState);
+						sb.append("/null/null");
+					}
+				}
+				
+				if(desired.containsKey("brightness")) {
+					brightness = ((int)desired.get("brightness"))/10 == 0 ? 1: ((int)desired.get("brightness"))/10;
+					sb.append("on").append("/").append(brightness).append("/null");
+				}
+				
+				break;
+				
+			case THINGS_INFO.THINGS_COLOR_LIGHT_DIMMER:
+				
+				if(capability.equals("Power") && desired.containsKey("power")) {
+					String tmpState = (String)desired.get("power");
+					if(tmpState.equals("on") || tmpState.equals("off")) {
+						sb.append(tmpState);
+					}
+				}
+				
+				
+				if(desired.containsKey("brightness")) {
+					brightness = ((int)desired.get("brightness"))/10 == 0 ? 1: ((int)desired.get("brightness"))/10;
+					sb.append("/").append(brightness);
+				}else {
+					sb.append("/null");
+				}
+				
+				
+				if(desired.containsKey("colorTemperature")) {
+					colorTemer = ((int)desired.get("colorTemperature"))/1000 == 0 ? 1:((int)desired.get("colorTemperature"))/1000;
+					sb.append("/").append(colorTemer);
+				}else {
+					sb.append("/null");
+				}
+				
 				break;
 				
 			case THINGS_INFO.THINGS_TEMPER:
 				if(capability.equals("Power") && desired.containsKey("power")) {
 					String tmpState = (String)desired.get("power");
 					if(tmpState.equals("on") || tmpState.equals("off")) sb.append(tmpState);
+					
+					if(tmpState.equals("on") && desired.containsKey("targetSetpoint")) sb.append("/").append(desired.get("targetSetpoint"));
 				}
 					
 				if(capability.equals("TemperatureSetpoint") && desired.containsKey("targetSetpoint")) {
 					sb.append("on/").append(desired.get("targetSetpoint"));
 				}
 				
+				
 				break;
 				
 			case THINGS_INFO.THINGS_GAS:
@@ -553,6 +703,12 @@ public class KakaoMsgHandler {
 				if(capability.equals("Power") && desired.containsKey("power")) {
 					String tmpState = (String)desired.get("power");
 					if(tmpState.equals("on") || tmpState.equals("off")) sb.append(tmpState);
+					
+					if(tmpState.equals("on") && desired.containsKey("fanSpeed")) {
+						String tmpFanSpeed = (String)desired.get("fanSpeed");
+						if(tmpFanSpeed.equals("low") || tmpFanSpeed.equals("middle") || tmpFanSpeed.equals("high"))
+							sb.append(desired.get("fanSpeed"));
+					}
 				}
 				
 				if(capability.equals("AirFlow") && desired.containsKey("fanSpeed")) {
@@ -564,8 +720,12 @@ public class KakaoMsgHandler {
 				break;
 				
 			case THINGS_INFO.THINGS_ELECPLUG: // 지원하지 않음
-				if(desired.containsKey("power")) sb.append(desired.get("power"));
-				else if(desired.containsKey("mode")) sb.append(desired.get("mode"));
+				if(capability.equals("Power") && desired.containsKey("power")) {
+					String tmpState = (String)desired.get("power");
+					if(tmpState.equals("on"))
+						sb.append("on");
+					else if(tmpState.equals("off")) sb.append("off");
+				}
 				break;
 				
 			case THINGS_INFO.THINGS_ELEVATOR:
@@ -594,10 +754,30 @@ public class KakaoMsgHandler {
 		
 		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(modelId);
 		String[] splitStr = status.split("\\/");
-		
+		int temp1, temp2 = 0;
 		switch(things.getEndPoint()) {
+		case THINGS_INFO.THINGS_ELECPLUG:
+			state.put("power", splitStr[1]);
+			
+			break;
 		case THINGS_INFO.THINGS_LIGHT:
-			state.put("power", status);
+		case THINGS_INFO.THINGS_LIGHT_DIMMER:
+		case THINGS_INFO.THINGS_COLOR_LIGHT_DIMMER:
+			
+			state.put("power", splitStr[0]);
+			
+			if(things.getEndPoint() == THINGS_INFO.THINGS_LIGHT) break; 
+				
+			if(splitStr[1] != null && !splitStr[1].equals("null")) {
+				temp1 = Integer.parseInt(splitStr[1]) * 10;
+				state.put("brightness", temp1);
+			}
+			
+			if(splitStr[2] != null && !splitStr[2].equals("null")) {
+				temp2 = (Integer.parseInt(splitStr[2])*1000);
+				state.put("colorMode", "colorTemperature");
+				state.put("colorTemperature", temp2);
+			}
 			break;
 		case THINGS_INFO.THINGS_TEMPER:
 			

+ 27 - 17
src/main/java/com/icontrols/kakao/socket/wallpad/ThreadServerHandler.java

@@ -93,7 +93,7 @@ public class ThreadServerHandler extends Thread {
 							
 							if (0 < sbInBuffer.toString().indexOf("</imap>")) { // </imap> 으로 제대로 닫혔다면 클라이언트의 이벤트 메세지를 제대로 수신 했다는 말.
 								bRcvOK = true;
-								logger.info("[iMAPSvrProc().run()] Received DONE!!");
+								logger.debug("[iMAPSvrProc().run()] Received DONE!!");
 								break;
 							}
 						} catch (Exception e) {
@@ -104,7 +104,7 @@ public class ThreadServerHandler extends Thread {
 						Thread.sleep(100);
 					}
 				} catch (Exception e) {
-					logger.info("[Exception] iMAPSvrProc.run() ===== 2 =====");
+					logger.error("[Exception] iMAPSvrProc.run() ===== 2 =====");
 					connectedClientSocket.close();
 					logger.error("message : " + e);
 					return;
@@ -120,8 +120,8 @@ public class ThreadServerHandler extends Thread {
 			}
 			
 			// 응답을 제대로 받은 이후의 처리 .. 제대로 된 응다블 받지 못했다면 위에서 소켓 연결 해제 
-			logger.info("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-");
-			logger.info("strRcvMSG :: > " + strRcvMSG);
+			logger.debug("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-");
+			logger.debug("strRcvMSG :: > " + strRcvMSG);
 			
 			strRcvMSG = strRcvMSG.substring(strRcvMSG.indexOf("<")); // 이 부분에 대한 예시 데이터가 있으면 이해하기 좋을거 같다. 테스트 하면서 뽑아내고 주석으로 잘아보자.
 			
@@ -139,15 +139,15 @@ public class ThreadServerHandler extends Thread {
 			// id 가 c2 인 Node의 val attribute 값 가져오기
 			Node service = (Node) xpath.evaluate("//imap/service", doc, XPathConstants.NODE);
 			String requestType = XmlUtil.getAttributeWithItem(service, "type");
-			logger.info("[ThreadServerHandler]-service type : " + requestType);
+			logger.debug("[ThreadServerHandler]-service type : " + requestType);
 			
 			String retXML = "";
 			if (requestType.equalsIgnoreCase("notice")) {
 				String requestCmd = XmlUtil.getAttributeWithItem(service, "name");
 				
-				logger.info("[ThreadServerHandler]-requestCmd : " + requestCmd);
+				logger.debug("[ThreadServerHandler]-requestCmd : " + requestCmd);
 //				if (requestCmd.equalsIgnoreCase("msg_device_event")) { // 상태변경이벤트인경우에 처리
-					logger.info("[ThreadServerHandler]-strRcvMSG : " + strRcvMSG);
+					logger.debug("[ThreadServerHandler]-strRcvMSG : " + strRcvMSG);
 					// 빈번하게 실행 될 가능성이 높다.
 					DeviceEventMsgHandler emh = new DeviceEventMsgHandler(doc, requestCmd);
 					emh.start();
@@ -189,11 +189,11 @@ public class ThreadServerHandler extends Thread {
 
 				// id 가 c2 인 Node의 val attribute 값 가져오기
 				Node iMap = (Node) xpath.evaluate("//imap", doc, XPathConstants.NODE);
-				logger.info("[DeviceEventMsgHandler] - address : " + iMap.getAttributes().getNamedItem("address").getTextContent());
-				logger.info("[DeviceEventMsgHandler] - sender : "  + iMap.getAttributes().getNamedItem("sender").getTextContent());
+				logger.debug("[DeviceEventMsgHandler] - address : " + iMap.getAttributes().getNamedItem("address").getTextContent());
+				logger.debug("[DeviceEventMsgHandler] - sender : "  + iMap.getAttributes().getNamedItem("sender").getTextContent());
 
 
-				String dongho = iMap.getAttributes().getNamedItem("sender").getTextContent();
+				String dongho = XmlUtil.getAttributeWithItem(iMap, "sender");
 				String searchDong = (dongho.indexOf("d") >= 0)?"d":"동";
 				String searchHo = (dongho.indexOf("d") >= 0)?"h":"호";
 
@@ -203,19 +203,20 @@ public class ThreadServerHandler extends Thread {
 				String dong = dongho.substring(0, idxdong).trim();
 				String ho = dongho.substring(idxdong + 1, idxho).trim();
 				
-				logger.info("[DeviceEventMsgHandler] - [동:" + dong + "호:" + ho + "]");
+				
 
 				Node service = (Node) xpath.evaluate("//imap/service", doc, XPathConstants.NODE);
-				logger.info(service.getAttributes().getNamedItem("type").getTextContent());
+				logger.debug(service.getAttributes().getNamedItem("type").getTextContent());
 
 				model_id = (String) xpath.evaluate("//imap/service/model_id ", doc, XPathConstants.STRING);
 				dev_num = Integer.parseInt((String) xpath.evaluate("//imap/service/dev_num", doc, XPathConstants.STRING));
 				status = (String) xpath.evaluate("//imap/service/status", doc, XPathConstants.STRING);
 				
-				logger.info("[DeviceEventMsgHandler] - model_id : " + model_id);
-				logger.info("[DeviceEventMsgHandler] - dev_num  : " + dev_num);
-				logger.info("[DeviceEventMsgHandler] - status   : " + status);
+				logger.debug("[DeviceEventMsgHandler] - model_id : " + model_id);
+				logger.debug("[DeviceEventMsgHandler] - dev_num  : " + dev_num);
+				logger.debug("[DeviceEventMsgHandler] - status   : " + status);
 
+				logger.info("[DeviceEventMsgHandler] - [동:" + dong + "호:" + ho + "] - [" + model_id + "] - [" + dev_num + "] - ["+status+"]");
 				String endpointId = model_id + "_" + dev_num;
 				
 				Map <String, Object> body = new HashMap<String, Object>();
@@ -234,7 +235,15 @@ public class ThreadServerHandler extends Thread {
 					dList.stream().filter(donghoInfo -> donghoInfo.getDeleteFlag().equals("N"))
 									.forEach(donghoInfo -> { 
 										try {
-											body.put(endpointId, KakaoMsgHandler.setDeviceState(endpointId, status));
+											Map<String, Object> state = KakaoMsgHandler.setDeviceState(endpointId, status);
+											
+											if(state.containsKey("colorTemperature") && state.containsKey("brightness")) {
+												body.put("colorDimmer_"+endpointId, state);
+											}else if(state.containsKey("brightness")) {
+												body.put("dimmer_"+endpointId, state);	
+											}else {
+												body.put(endpointId, state);
+											}
 											logger.debug("body --> " + body.toString());
 											
 											Map<String, Object> sendMap = kakaoMsgHandler.setKakaoEventMsg(donghoInfo, body);
@@ -266,7 +275,8 @@ public class ThreadServerHandler extends Thread {
 							if(code == KAKAO_RESULT.SUCCESS) {
 								logger.info("[EVENT SUCCESS] - " + message);
 							} else {
-								logger.error("[EVENT ERROR] - " + message);
+								logger.error("[EVENT ERROR] - [CODE-" + code + "]" + message);
+								
 							}							
 						}catch(Exception e) {
 							logger.error("[ERROR - future get] - " + e.getMessage());

+ 39 - 1
src/main/java/com/icontrols/kakao/socket/wallpad/WallpadMsgSender.java

@@ -80,7 +80,8 @@ public class WallpadMsgSender {
 			.append(XMLGenerator.MakeXMLTail());
 		
 			xmlData = sb.toString();
-			
+			logger.info("[SUBS]");
+			logger.info(sb.toString());
 			int bRet = imapSocket.doWork(xmlData);
 			
 			if(bRet < 0) {
@@ -140,6 +141,43 @@ public class WallpadMsgSender {
 		}
 	}
 	
+	public Document remoteRegisterNewDevice(Map<String, Object> param) {
+		Document doc = null;
+		int dong = Integer.parseInt((String)param.get("dong"));
+		int ho = Integer.parseInt((String)param.get("ho"));
+
+		String alias = "KAKAO HOME";
+		String twinid = UUID.randomUUID().toString();
+		String targetIP = IPGenerator.getIPFromDongHo(dong, ho);
+		try {
+			iMapRequestSync imapSocket = new iMapRequestSync(
+					IPGenerator.getIPFromDongHo(dong, ho),
+					SERVERINFO.clientNewPort);
+			
+			String xmlData = null;
+			StringBuffer sb = new StringBuffer();
+			
+			sb.append(XMLGenerator.MakeXMLHeaderForNotice(REMOTE_KIND.remote_register_new_device_auth_number.getContents()))
+			.append("      <home_info dong=\"").append(dong).append("\" ho=\"").append(ho).append("\" ip=\"").append(targetIP).append("\" type=\"main\"/>\r\n")
+			.append("      <device_info alias=\"" + alias + "\" twinid=\"" + twinid).append("\" />\r\n")
+			.append(XMLGenerator.MakeXMLTail());
+		
+			xmlData = sb.toString();
+			
+			int bRet = imapSocket.doWork(xmlData);
+			
+			if(bRet < 0) {
+				logger.error("[remoteDeviceList ERROR] - document null");
+				return null;
+			}
+			
+			return imapSocket.getDocument();
+		}catch(Exception e) {
+			logger.error("[remoteDeviceList ERROR] - " + e.getMessage());
+			return null;
+		}
+	}
+	
 	/**
 	 * 월패드와 연결된 기기목록을 요청한다 
 	 * @param dong

+ 6 - 3
src/main/resources/application.properties

@@ -1,16 +1,19 @@
 logging.config=classpath:logback-spring.xml
 
-## local 황의현 개발 디비
+## local 황의현 개발 디비
 #spring.datasource.url=jdbc:mariadb://localhost:33060/platform_danzi?useUnicode=true&charaterEncoding=utf-8
 #spring.datasource.username=root
 #spring.datasource.password=pangpang
 
-## 단지서버 디비
+## 배포용-테스트 단지서버
 spring.datasource.url=jdbc:mariadb://192.168.100.155:8005/platform_danzi?useUnicode=true&charaterEncoding=utf-8
+
+## 배포용-카카오데모서버
+##spring.datasource.url=jdbc:mariadb://localhost:8005/platform_danzi?useUnicode=true&charaterEncoding=utf-8
 spring.datasource.username=valley
 spring.datasource.password=valley123
 
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.generate-ddl=true
 
-server.port=8002
+server.port=8003

+ 2 - 2
src/main/resources/logback-spring.xml

@@ -19,8 +19,8 @@
             <pattern>[DANZI] %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
         </encoder>
     </appender>
-
-    <logger name="com.icontrols.kakao" level="INFO"></logger>
+                                                                                                                           
+    <logger name="com.icontrols.kakao" level="DEBUG"></logger>
 
     <root level="INFO">
         <appender-ref ref="dailyRollingFileAppender" />