Browse Source

디밍 / 색온도 조명 기능 추가. (해당버전은 월패드에서 지원되면 적용한다.)

pangs 6 years ago
parent
commit
d0ef6f9cdb

+ 59 - 36
src/main/java/com/icontrols/kakao/common/THINGS_INFO.java

@@ -5,14 +5,21 @@ import java.util.Arrays;
 import com.icontrols.kakao.common.utils.BeanUtils;
 import com.icontrols.kakao.repo.ThingsInfoRepository;
 
+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\" } ] }"),
@@ -40,19 +47,29 @@ 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",		"주방난방")
 		;
 		
 		
@@ -98,22 +115,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, "ELEVATOR", 		"ElevatorCaller", 		"엘리베이터"),
+		VISITOR			(15, "VISITOR", 		"visitor", 				"방문자"),
+		EMERGENCY		(16, "EMERGENCY", 		"emergency", 			"방범"),
+		LIGHTDIMMER		(17, "DIMMER", 	"LightDimmer", 			"디밍제어 조명"),
+		COLORLIGHTDIMMER(18, "COLORDIMMER", "ColorLightDimmer", 	"색온도 디밍제어 조명")
 		;
 		
 		private int endPoint;
@@ -165,9 +184,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,20 +194,24 @@ 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())) {
+				System.out.println(splitModelId[0] + "--" + things.getThingsName());
 				return things;
 			}
 		}
-		
 		return null;
 	}
 	

+ 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();
+	}
 }

+ 0 - 2
src/main/java/com/icontrols/kakao/controller/KakaoDanziController.java

@@ -49,8 +49,6 @@ public class KakaoDanziController {
 														HttpServletResponse response, 
 														HttpServletRequest request
 														) throws Exception{
-		
-		
 		try {
 			String requestId = (String)params.get("id");
 			String requestType = (String) params.get("type");

+ 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")

+ 165 - 51
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;
@@ -89,7 +91,7 @@ public class KakaoMsgHandler {
 			.append("      <device_info alias=\"").append(alias).append("\" twinid=\"").append(twinid).append("\" auth_number=\"" + code + "\" />\r\n")
 			.append(XMLGenerator.MakeXMLTail());
 			
-			logger.info(sb.toString());
+			logger.debug(sb.toString());
 			
 			SSLClient.sendToWallpad(targetIP, sb.toString());
 			
@@ -137,6 +139,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 +156,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 +168,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를 가진다.
+
+							// 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")) {
 								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 +212,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 +310,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[0]:tmpSplit[1];
 		
 		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,6 +329,7 @@ public class KakaoMsgHandler {
 			logger.error("[ERROR] - things null ==> INVALID REQ");
 			return retMap;
 		}
+		
 		String action = KakaoMsgHandler.setDeviceActionStr(modelId, actionName, desired);
 		
 		if(action.length() == 0) {
@@ -346,7 +366,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 +383,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 +417,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 +426,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 +449,14 @@ 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:
 			break;
 		}
-		
 		Map<String, Object> capabilities = CommonUtil.jsonToMap(jsonString);
 		
 		return capabilities;
@@ -437,35 +471,53 @@ 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[1].equals("null") && strSplit[2].equals("null")) 
+								endpointId = "dimmer_"+endpointId;
+							else if(!strSplit[2].equals("null"))
+								endpointId = "colorDimmer_"+endpointId;
+						}
+						
+			 			String tmpModelId = cNodeName.equals("temper")?endpointId:cNodeName;
+						
+			 			
+						
+						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 +533,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);
@@ -529,6 +590,36 @@ public class KakaoMsgHandler {
 				}
 				
 				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);
+				}
+				
+				if(desired.containsKey("brightness")) {
+					sb.append("/").append(((int)desired.get("brightness"))/10*10);
+				}
+				
+				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")) {
+					sb.append("/").append(((int)desired.get("brightness"))/10*10);
+				}else if(!desired.containsKey("brightness") && desired.containsKey("colorTemperature")) {
+					sb.append("/null");
+				}
+				
+				if(desired.containsKey("colorTemperature")) {
+					sb.append("/").append(((int)desired.get("colorTemperature"))/1000*10);
+				}
+				break;
 				
 			case THINGS_INFO.THINGS_TEMPER:
 				if(capability.equals("Power") && desired.containsKey("power")) {
@@ -594,10 +685,33 @@ 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_LIGHT:
-			state.put("power", status);
+			state.put("power", splitStr[0]);
+			break;
+		case THINGS_INFO.THINGS_LIGHT_DIMMER:
+			state.put("power", splitStr[0]);
+			if(!splitStr[1].equals("null")) {
+				temp1 = Integer.parseInt(splitStr[1]);
+				state.put("brightness", temp1);
+			}
+			break;
+		case THINGS_INFO.THINGS_COLOR_LIGHT_DIMMER:
+			
+			state.put("power", splitStr[0]);
+			
+
+			if(!splitStr[1].equals("null")) {
+				temp1 = Integer.parseInt(splitStr[1]);
+				state.put("brightness", temp1);
+			}
+			
+			if(!splitStr[2].equals("null")) {
+				temp2 = (Integer.parseInt(splitStr[2])*1000);
+				state.put("colorMode", "colorTemperature");
+				state.put("colorTemperature", temp2);
+			}
 			break;
 		case THINGS_INFO.THINGS_TEMPER:
 			

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

@@ -193,7 +193,7 @@ public class ThreadServerHandler extends Thread {
 				logger.info("[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":"호";
 

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

@@ -19,7 +19,7 @@
             <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>
 
     <root level="INFO">