#3 동탄아이파크현장 적용본

Đã hợp nhất
alalssg đã nhập 3 commit từ HomeNetServer/dimming_version vào [3]s 5 năm trước cách đây

+ 4 - 3
src/main/java/com/icontrols/kakao/common/SERVERINFO.java

@@ -20,7 +20,8 @@ public class SERVERINFO {
 	// public static final String SendEventIP = "http://112.220.212.226"; //이통사 상용서버
 	
 	public static final String SendDevEventURL = "http://localhost"; // 중계서버로 변경해야함.
-	public static final String SendKakaoEventURL = "https://teldev.hdc-smart.com"; // 중계서버로 변경해야함.
+	public static final String SendKakaoEventURL = "https://telproxy.hdc-smart.com"; // 중계서버로 변경해야함.
+//	public static final String SendKakaoEventURL = "https://teldev.hdc-smart.com"; // 중계서버로 변경해야함.
 //	public static final String SendKakaoEventURL = "https://kakaohome-api.i.kakao.com"; // 중계서버로 변경해야함.
 	
 	public static String SendEventURL = "https://hdc-smart.com";
@@ -37,8 +38,8 @@ public class SERVERINFO {
 
 	public static boolean GasCount_HardCoding_One = false;
 
-	public static final String KAKAO_HEADER_CLIENT_ID = "XMPHQZVWXI";
-	public static final String KAKAO_HEADER_CLIENT_SECRET = "SCJMXYNDVSNKOPRCRKHS";
+	public static final String KAKAO_HEADER_CLIENT_ID = "MPAHXKWELS";
+	public static final String KAKAO_HEADER_CLIENT_SECRET = "SHDPEOWJSKDZALQXLDNS";
 	
 	public static final String KAKAO_EVENT_CLIENT_ID = "pkevk1F4cKHzs7rN4MHe25wYnUm3kRvh";
 	public static final String KAKAO_EVENT_CLIENT_SECRET = "pF2UrvbhkAqbptG4SyrsUU5pTB1DWtqm";

+ 27 - 23
src/main/java/com/icontrols/kakao/common/THINGS_INFO.java

@@ -23,7 +23,7 @@ public final class THINGS_INFO {
 		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\"} ]}"),
+		COLOR_LIGHT_DIMMER("colorDimming", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Brightness\" }, { \"name\" : \"ColorMode\"}, { \"name\" : \"ColorTemperature\", \"attributes\" : { \"colorTemperature\": { \"min\":3000, \"max\":5700 } } } ]}"),
 		TEMPER("temper", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Temperature\" }, { \"name\" : \"TemperatureSetpoint\" } ]}"),
 		VENTIL("ventil","{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"AirFlow\" } ]}"),
 		GAS("gas","{\"capabilities\" : [ { \"name\" : \"Lock\" } ] }"),
@@ -53,33 +53,37 @@ public final class THINGS_INFO {
 	
 	public enum DEVICE_DETAIL{
 		LIVINGLIGHT					("livinglight", 				"Light", 			"거실조명"),
-		LIGHT01						("light01",						"Light",			"안방조명"),
-		LIGHT02						("light02",						"Light",			"서재조명"),
-		LIGHT03						("light03",						"Light",			"작은방조명"),
-		LIGHT04						("light04",						"Light",			"주방조명"),
+		LIGHT01						("light01",						"Light",			"주방조명"),
+		LIGHT02						("light02",						"Light",			"방1조명"),
+		LIGHT03						("light03",						"Light",			"방2조명"),
+		LIGHT04						("light04",						"Light",			"방3조명"),
+		LIGHT05						("light05",						"Light",			"방4조명"),
 		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",		"주방조명"),
+		DIMMER_LIGHT01				("dimmer_light01",				"LightDimmer",		"주방조명"),
+		DIMMER_LIGHT02				("dimmer_light02",				"LightDimmer",		"방1조명"),
+		DIMMER_LIGHT03				("dimmer_light03",				"LightDimmer",		"방2조명"),
+		DIMMER_LIGHT04				("dimmer_light04",				"LightDimmer",		"방3조명"),
+		DIMMER_LIGHT05				("dimmer_light05",				"LightDimmer",		"방4조명"),
 		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",	"주방조명"),
+		COLOR_DIMMER_LIGHT01		("colorDimmer_light01",			"ColorLightDimmer",	"주방조명"),
+		COLOR_DIMMER_LIGHT02		("colorDimmer_light02",			"ColorLightDimmer",	"방1조명"),
+		COLOR_DIMMER_LIGHT03		("colorDimmer_light03",			"ColorLightDimmer",	"방2조명"),
+		COLOR_DIMMER_LIGHT04		("colorDimmer_light04",			"ColorLightDimmer",	"방3조명"),
+		COLOR_DIMMER_LIGHT05		("colorDimmer_light05",			"ColorLightDimmer",	"방4조명"),
 		VENTIL						("ventil",						"AirVentilator",	"환기"),
 		GAS							("gas",							"GasValve",			"가스밸브"),
-		ELEVATOR					("ElevatorCaller",				"ElevatorCaller",	"엘리베이터"),
+		ELEVATOR					("elevator",					"ElevatorCaller",	"엘리베이터"),
 		TEMPER1						("temper_1",					"FloorHeater",		"거실난방"),
-		TEMPER2						("temper_2",					"FloorHeater",		"방난방"),
-		TEMPER3						("temper_3",					"FloorHeater",		"서재난방"),
-		TEMPER4						("temper_4",					"FloorHeater",		"작은방난방"),
-		TEMPER5						("temper_5",					"FloorHeater",		"방난방"),
+		TEMPER2						("temper_2",					"FloorHeater",		"방1난방"),
+		TEMPER3						("temper_3",					"FloorHeater",		"방2난방"),
+		TEMPER4						("temper_4",					"FloorHeater",		"방3난방"),
+		TEMPER5						("temper_5",					"FloorHeater",		"방4난방"),
 		ELECTRIC01					("electric01",					"PowerOutlet",		"거실콘센트"),
-		ELECTRIC02					("electric02",					"PowerOutlet",		"안방콘센트"),
-		ELECTRIC03					("electric03",					"PowerOutlet",		"서재콘센트"),
-		ELECTRIC04					("electric04",					"PowerOutlet",		"작은방콘센트"),
-		ELECTRIC05					("electric05",					"PowerOutlet",		"주방콘센트")
+		ELECTRIC02					("electric02",					"PowerOutlet",		"주방콘센트"),
+		ELECTRIC03					("electric03",					"PowerOutlet",		"방1콘센트"),
+		ELECTRIC04					("electric04",					"PowerOutlet",		"방2콘센트"),
+		ELECTRIC05					("electric05",					"PowerOutlet",		"방3콘센트"),
+		ELECTRIC06					("electric06",					"PowerOutlet",		"방4콘센트")
 		;
 		
 		
@@ -138,7 +142,7 @@ public final class THINGS_INFO {
 		PARCEL			(11, "PARCEL", 			"parcel", 				"택배도착"),
 		HEMS			(12, "HEMS", 			"hems", 				"원격검침"),
 		CARIN			(13, "CARIN", 			"carin", 				"주차관제(입차/출차)"),
-		ELEVATOR		(14, "ELEVATORCALLER",	"ElevatorCaller", 		"엘리베이터"),
+		ELEVATOR		(14, "elevator",		"ElevatorCaller", 		"엘리베이터"),
 		VISITOR			(15, "VISITOR", 		"visitor", 				"방문자"),
 		EMERGENCY		(16, "EMERGENCY", 		"emergency", 			"방범"),
 		LIGHTDIMMER		(17, "DIMMER", 	"LightDimmer", 			"디밍제어 조명"),

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

@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.icontrols.kakao.common.utils.CommonUtil;
 import com.icontrols.kakao.service.AccessTokenService;
 
 @RestController
@@ -57,6 +58,7 @@ public class AccessTokenController {
 		
 		retMap.put("id", reqId);
 		retMap.put("type", type);
+		logger.info("[accessToken] RESULT - " + retMap.toString());
 		return retMap;
 	}
 }

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

@@ -103,7 +103,7 @@ public class KakaoDanziController {
 				retMap = params;
 			}
 		}catch(Exception e) {
-			logger.error("[Unknown ERROR]");
+			logger.error("[Unknown ERROR]" + e.getMessage());
 			e.printStackTrace();
 			retMap = KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL);
 		}finally {

+ 36 - 25
src/main/java/com/icontrols/kakao/service/impl/AccessTokenServiceImpl.java

@@ -23,10 +23,10 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 	private final Logger logger = LoggerFactory.getLogger(AccessTokenServiceImpl.class);
 	
 	
-	private final String ERROR_CODE_INTERNAL = "InternalServerError";
-	private final String ERROR_UNLINK_SERVICE = "UnlinkService";
-	private final String ERROR_TOKEN_NONE_EXIST = "TokenNoneExistent";
-	private final String ERROR_ALREADY_CREATED_TOKEN = "AlreadyCreatedToken";
+//	private final String ERROR_CODE_INTERNAL = "InternalServerError";
+//	private final String ERROR_UNLINK_SERVICE = "UnlinkService";
+//	private final String ERROR_TOKEN_NONE_EXIST = "TokenNoneExistent";
+//	private final String ERROR_ALREADY_CREATED_TOKEN = "AlreadyCreatedToken";
 	
 	@Autowired
 	DonghoInfoRepository donghoRepo;
@@ -82,7 +82,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			
 			if(uList.size() > 0) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				errMap.put("message", ERROR_ALREADY_CREATED_TOKEN);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//				errMap.put("message", ERROR_ALREADY_CREATED_TOKEN);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[CREATE] - [ERROR] - ALREADY CREATED TOKEN");
@@ -101,14 +103,15 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 		
 		}catch(Exception e) {
 			Map<String, Object> errMap = new HashMap<String, Object>();
-			errMap.put("message", ERROR_CODE_INTERNAL);
+			errMap.put("code", KAKAO_RESULT.CODE.FAIL_INTERNAL.getResultCode());
+			errMap.put("message", KAKAO_RESULT.CODE.FAIL_INTERNAL.getMessage());
 			
 			retMap.put("error", errMap);
 			logger.error("[AccessTokenService]-[CREATE] - [ERROR] - " + e.getMessage());
 			
 			e.printStackTrace();
 		}finally {
-			logger.info("AccessTokenService [CREATE] - " + retMap.toString());
+			logger.info("AccessTokenService [CREATE] - [END] - " + retMap.toString());
 		}
 		
 		return retMap;
@@ -132,8 +135,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			// 1.1 DonghoInfo가 없으면 ERROR Return
 			if(userInfoList.size() == 0) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - TOKEN NONE EXIST1");
@@ -145,8 +149,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			logger.debug("prev dongho = " + userInfo.getDonghoInfo().getDonghoId() + "_ NEW dongho = " + dong_ho);
 			if(!userInfo.getDonghoInfo().getDonghoId().equals(dong_ho)) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - TOKEN NONE EXIST2");
@@ -155,8 +160,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			
 			if(userInfo.getDeleteFlag().equals("Y")) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_UNLINK_SERVICE);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_UNLINKEXTENSION_SERVICE.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_UNLINKEXTENSION_SERVICE.getMessage());
+//				errMap.put("message", ERROR_UNLINK_SERVICE);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - UNLINK TOKEN - " + userInfo.getDeleteType());
@@ -170,13 +176,14 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			userInfoRepo.save(userInfo);
 		}catch(Exception e) {
 			Map<String, Object> errMap = new HashMap<String, Object>();
-			
-			errMap.put("message", ERROR_CODE_INTERNAL);
+			errMap.put("code", KAKAO_RESULT.CODE.FAIL_INTERNAL.getResultCode());
+			errMap.put("message", KAKAO_RESULT.CODE.FAIL_INTERNAL.getMessage());
+//			errMap.put("message", ERROR_CODE_INTERNAL);
 			logger.error("[AccessTokenService] - [REFRESH] - [ERROR] - " + e.getMessage());
 			retMap.put("error", errMap);
 			e.printStackTrace();
 		}finally {
-			logger.info("AccessTokenService [REFRESH] - " + retMap.toString());
+			logger.info("AccessTokenService [REFRESH] - [END] - " + retMap.toString());
 		}
 		return retMap;
 	}
@@ -199,8 +206,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			// 1.1 DonghoInfo가 없으면 ERROR Return
 			if(userList.size() == 0) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - TOKEN NONE EXIST");
@@ -212,8 +220,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			// 호옥시이나아 같은 동호가 아닐 수도 있으니깐
 			if(!userInfo.getDonghoInfo().getDonghoId().equals(dong_ho)) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//				errMap.put("message", ERROR_TOKEN_NONE_EXIST);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - TOKEN NONE EXIST");
@@ -222,8 +231,9 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			
 			if(userInfo.getDeleteFlag().equals("Y")) {
 				Map<String, Object> errMap = new HashMap<String, Object>();
-				
-				errMap.put("message", ERROR_UNLINK_SERVICE);
+				errMap.put("code", KAKAO_RESULT.CODE.FAIL_UNLINKEXTENSION_SERVICE.getResultCode());
+				errMap.put("message", KAKAO_RESULT.CODE.FAIL_UNLINKEXTENSION_SERVICE.getMessage());
+//				errMap.put("message", ERROR_UNLINK_SERVICE);
 				
 				retMap.put("error", errMap);
 				logger.error("[AccessTokenService]-[REFRESH] - [ERROR] - UNLINK TOKEN - " + userInfo.getDeleteType());
@@ -238,12 +248,13 @@ public class AccessTokenServiceImpl implements AccessTokenService {
 			}
 		}catch(Exception e) {
 			Map<String, Object> errMap = new HashMap<String, Object>();
-			
-			errMap.put("message", ERROR_TOKEN_NONE_EXIST);
+			errMap.put("code", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getResultCode());
+			errMap.put("message", KAKAO_RESULT.CODE.FAIL_INVALID_TOKEN.getMessage());
+//			errMap.put("message", ERROR_TOKEN_NONE_EXIST);
 			
 			retMap.put("error", errMap);
 		}finally {
-			logger.info("AccessTokenService [GET] - " + retMap.toString());
+			logger.info("AccessTokenService [GET] - [END] - " + retMap.toString());
 		}
 		return retMap;
 	}

+ 17 - 15
src/main/java/com/icontrols/kakao/service/impl/KakaoExtensionServiceImpl.java

@@ -89,6 +89,20 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 				return param;
 			}
 			
+			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);
+			
 			// 기기목록 조회 및 저장
 			List<ThingsInfo> databaseThingsList = thingsInfoRepository.findByDongAndHo(dong_ho.split("/")[0], dong_ho.split("/")[1]);
 			
@@ -115,21 +129,6 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 			
 			logger.debug("userInfo saved complete " );
 			
-			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);
-			
-			
 		}catch(Exception e) {
 			logger.error("[Auth Database Insert Error]");
 			param.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
@@ -256,12 +255,15 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 		List<ThingsInfo> thingsInfoList = thingsInfoRepository.findByDongAndHoAndEndpointId(Integer.toString(dong), Integer.toString(ho), endpointId);
 		
 		if(thingsInfoList == null || thingsInfoList.size() == 0) {
+			logger.error("[UPDATE-ERROR] - " + dong + "/" + ho + " - "+ endpointId + " is not exist");
 			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);

+ 2 - 1
src/main/java/com/icontrols/kakao/socket/utils/SSLClient.java

@@ -83,7 +83,8 @@ public class SSLClient {
 			logger.info("-->ip address -- " + mInetAddress + " -- " + port);
 			sslSocket = sf.createSocket(mInetAddress, port);
 		} catch (Exception e) {
-			logger.info("[SSLClient] TLS Socket Make Exception Error");
+			logger.error("[SSLClient] TLS Socket Make Exception Error");
+			logger.error("[SSLClient] message : " + e.getMessage());
 			e.printStackTrace();
 		}
 	}

+ 16 - 7
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoEventHandler.java

@@ -13,6 +13,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
@@ -34,6 +35,7 @@ import com.icontrols.kakao.entity.DonghoInfo;
 import com.icontrols.kakao.entity.UserInfo;
 import com.icontrols.kakao.repo.DonghoInfoRepository;
 import com.icontrols.kakao.repo.UserInfoRepository;
+import com.icontrols.kakao.service.AuthService;
 
 @Service("kakaoEventHandler")
 public class KakaoEventHandler {
@@ -48,6 +50,9 @@ public class KakaoEventHandler {
 	@Resource(name="wallpadMsgSender")
 	private WallpadMsgSender wallpadMsgSender;
 	
+	@Autowired
+	private AuthService authService;
+	
 	@Async("eventExecutor")
 	public CompletableFuture<Map<String, Object>> sendEventAsync(UserInfo userInfo, Map<String, Object> params) throws InterruptedException{
 		Map<String, Object> retMap = new HashMap<String, Object>();
@@ -82,7 +87,7 @@ public class KakaoEventHandler {
 			Map<String, Object> sendResult = sendStatusResult(userInfo, params);
 			
 			int code = (int) sendResult.get("result");
-			
+			logger.info("[EVENT RESULT] - ["+code+"]");
 			UserInfoRepository repo = null;
 			switch(code) {
 			case KAKAO_RESULT.FAIL_INTERNAL:
@@ -108,6 +113,7 @@ public class KakaoEventHandler {
 				retMap.put("message", "ID-["+userInfo.getId() + "]-FAIL_UNLINKEXTENSION_SERVICE");
 				
 				// 월패드 해지요청
+				new UnlinkExtensionHandler(userInfo.getDonghoInfo().getDong(), userInfo.getDonghoInfo().getHo()).start();
 				
 				break;
 			case KAKAO_RESULT.FAIL_EXPIREDTOKEN:  // 만료된 토큰, 토큰 재발급 뒤 재시도.
@@ -144,10 +150,9 @@ public class KakaoEventHandler {
 			}
 		}catch(Exception e) {
 			retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
-			
-			retMap.put("message", "ID-["+userInfo.getId() + "]-" + e.getMessage());
-			logger.error("ERROR" + e.getStackTrace());
+			logger.error("[ERROR] - " + e.getMessage());
 			e.printStackTrace();
+			retMap.put("message", "event send Error = " + e.getMessage());
 		}
 		
 		return CompletableFuture.completedFuture(retMap);
@@ -255,8 +260,8 @@ public class KakaoEventHandler {
 		HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(parameters, headers);
 		
 		String url = SERVERINFO.isDev?SERVERINFO.SendDevEventURL + ":" + SERVERINFO.SendDevEventPort + "/events/token":SERVERINFO.SendKakaoEventURL + ":" + SERVERINFO.SendKakaoEventPort +"/events/token";
-//		String url = "https://kakaohome-api.i.kakao.com/events/token";
 		
+//		String url = "https://kakaohome-api.i.kakao.com/events/token";
 		logger.debug("[TOKEN REFRESH REQUEST] URL : " + url);
 		logger.debug("[TOKEN REFRESH REQUEST] header : " + headers.toString());
 		logger.debug("[TOKEN REFRESH REQUEST] return value : " + entity.toString());
@@ -293,9 +298,13 @@ public class KakaoEventHandler {
 				return userInfo;
 			}
 		}catch(Exception e) {
-			logger.error("[TOKEN REFRESH REQUEST ERROR] - " + e.getMessage());
 			
-			e.printStackTrace();
+			if( e != null) {
+				logger.error("[TOKEN REFRESH REQUEST ERROR] - " + e.getMessage());
+			
+				e.printStackTrace();
+			}else
+				logger.error("Token REFRESH REQUEST ERROR]");
 		}
 		
 		logger.error("****************************************************");

+ 48 - 15
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoMsgHandler.java

@@ -184,11 +184,11 @@ public class KakaoMsgHandler {
 									String childName = j < 10 ? tmpModelId+"0"+j : tmpModelId+j;
 									Node childNode = (Node)xpath.evaluate("//imap/service/devinfo/*[@name='"+ childName +"']", doc, XPathConstants.NODE);
 									logger.debug("childName = " + childName);
-									childCount = Integer.parseInt(XmlUtil.getAttributeWithItem(childNode, "value"));
+									int tmpChildCount = Integer.parseInt(XmlUtil.getAttributeWithItem(childNode, "value"));
 									
 									NodeList childList = (NodeList)xpath.evaluate("//imap/service/devinfo/subdevinfo/*[@name='"+ childName +"']", doc, XPathConstants.NODESET);
 									
-									thingList.addAll(getChildThingsInfoList(dong, ho, childCount, childList));
+									thingList.addAll(getChildThingsInfoList(dong, ho, tmpChildCount, childList));
 								}
 							}else {
 								NodeList childList = (NodeList)xpath.evaluate("//imap/service/devinfo/*[@name='"+ tmpModelId +"']", doc, XPathConstants.NODESET);
@@ -255,7 +255,7 @@ public class KakaoMsgHandler {
 						int childCount = Integer.parseInt(XmlUtil.getAttributeWithItem(pNode, "value"));
 						
 						List<Map<String, Object>> childNodeInfoList = null;
-						logger.debug("tmpModelID --> " + tmpModelId);
+						logger.debug("tmpModelID --> " + tmpModelId + "childCount = " + childCount);
 						try {
 							// subdevinfo 를 가지고 있는 THINGS일 경우는 subdevinfo 들을 다시 구해야 한다.
 							// 예를들어 light는 light01 ~ 05 등의 subdevinfo를 가진다.
@@ -274,12 +274,19 @@ public class KakaoMsgHandler {
 								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);
-									logger.debug("childName = " + childName);
-									childCount = Integer.parseInt(XmlUtil.getAttributeWithItem(childNode, "value"));
+									logger.debug("childName = " + childName + " // j = " + j);
+									
+									if(childNode == null) continue;
+									
+									String tmpValue = XmlUtil.getAttributeWithItem(childNode, "value");
+									
+									if(tmpValue == null) continue;
+									
+									int tmpchildCount = Integer.parseInt(tmpValue);
 									
 									NodeList childList = (NodeList)xpath.evaluate("//imap/service/devinfo/subdevinfo/*[@name='"+ childName +"']", doc, XPathConstants.NODESET);
 									
-									childNodeInfoList = getChildDeviceInfo(childCount, childList);
+									childNodeInfoList = getChildDeviceInfo(tmpchildCount, childList);
 									logger.debug("child-->>" + childNodeInfoList.toString());
 									if(childNodeInfoList != null)
 										childNodeInfoList.forEach(tMap -> { body.putAll(tMap); });
@@ -306,8 +313,8 @@ public class KakaoMsgHandler {
 			
 			eleMap.put("displayType", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
 			eleMap.putAll(getDeviceCapabilities(THINGS_INFO.THINGS.ELEVATOR.getThingsName(), null));
-			eleMap.put("endpointId", "elevator");
-			eleMap.put("name", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
+			eleMap.put("endpointId", THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getModelId());
+			eleMap.put("name", THINGS_INFO.THINGS.ELEVATOR.getDesc());
 			eleMap.put("state", new HashMap<String, Object>());
 			
 			body.put("elevator", eleMap);
@@ -388,7 +395,11 @@ public class KakaoMsgHandler {
 		String[] tmpSplit = endpointId.split("_");
 		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())) {
+		//엘리베이터 특정. -> 엘리베이터는 tmpSplit length가 1이다.
+		// 모드 endpoint id는 _ <- 언더바가 포함돼 있지만 엘리베이터는 그렇지 않음
+		// 엘리베이터가 아닌데도 tmpSplit length가 1인경우는 존재하지 않는 디바이스로 간주.
+		if(tmpSplit.length == 1 && !modelId.equals(THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getModelId())) {
+			logger.error("[sendDeviceAction ERROR] - this is NonExist => " + modelId);
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_NONEXIST));
 			return retMap;
 		}
@@ -396,7 +407,7 @@ public class KakaoMsgHandler {
 		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 if(modelId.equals(THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getModelId())) devNum = 1;
 		else devNum = Integer.parseInt(tmpSplit[1]);
 		THINGS_INFO.THINGS things = THINGS_INFO.getThingsType(endpointId);
 		
@@ -736,13 +747,15 @@ public class KakaoMsgHandler {
 		logger.debug("ACTION STATUS --> " + desired.toString());
 		try {
 			int brightness = 1;
-			int colorTemer = 1;
+			int colorTemper = 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);
+					
+					sb.append("/null/null");
 				}
 				
 				break;
@@ -775,19 +788,39 @@ public class KakaoMsgHandler {
 				
 				if(desired.containsKey("brightness")) {
 					brightness = ((int)desired.get("brightness"))/10 == 0 ? 1: ((int)desired.get("brightness"))/10;
-					sb.append("/").append(brightness);
+					if(desired.containsKey("power"))
+						sb.append("/").append(brightness);
+					else
+						sb.append("on/").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);
+//					colorTemper = ((int)desired.get("colorTemperature"))/1000 == 0 ? 1:((int)desired.get("colorTemperature"))/1000;
+					int tmpColorTemp = (int)desired.get("colorTemperature");
+					
+					if(tmpColorTemp < 3000) tmpColorTemp = 3000;
+					else if(tmpColorTemp > 5700) tmpColorTemp = 5700;
+					
+					colorTemper = (tmpColorTemp)/300 - 9;
+					if(desired.containsKey("power"))
+						sb.append("/").append(colorTemper);
+					else {
+						if(desired.containsKey("brightness")) {
+							sb.append("/").append(colorTemper);	
+						}else {
+							sb = new StringBuffer();
+							sb.append("on/null/").append(colorTemper);
+						}
+						
+					}
 				}else {
 					sb.append("/null");
 				}
 				
+				
 				break;
 				
 			case THINGS_INFO.THINGS_TEMPER:
@@ -888,7 +921,7 @@ public class KakaoMsgHandler {
 			}
 			
 			if(splitStr[2] != null && !splitStr[2].equals("null")) {
-				temp2 = (Integer.parseInt(splitStr[2])*1000);
+				temp2 = ((Integer.parseInt(splitStr[2])+9)*300);
 				state.put("colorMode", "colorTemperature");
 				state.put("colorTemperature", temp2);
 			}

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

@@ -223,8 +223,8 @@ public class ThreadServerHandler extends Thread {
 				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);
+				dev_num = status.equalsIgnoreCase("unsubscription")?1:Integer.parseInt((String) xpath.evaluate("//imap/service/dev_num", doc, XPathConstants.STRING));
 				
 				logger.debug("[DeviceEventMsgHandler] - model_id : " + model_id);
 				logger.debug("[DeviceEventMsgHandler] - dev_num  : " + dev_num);
@@ -241,6 +241,12 @@ public class ThreadServerHandler extends Thread {
 					//dong ho 가  같은 유저 모두 조회
 					
 					List<DonghoInfo> dList = repo.findByDongAndHo(dong, ho);
+					
+					if(dList.size() == 0) {
+						logger.info("[EVENT] - 해동 동 호 인원 없음 프로세스 종료");
+						
+						return;
+					}
 					KakaoEventHandler kakaoEventHandler = (KakaoEventHandler)BeanUtils.getBean("kakaoEventHandler");
 					
 					List<CompletableFuture<Map<String, Object>>> fList = new ArrayList<>();
@@ -248,22 +254,22 @@ public class ThreadServerHandler extends Thread {
 					
 					Map<String, Object> state = KakaoMsgHandler.setDeviceState(endpointId, status);
 					
-					logger.info(userSet.toString());
 					userSet.stream()
 						.filter(userInfo -> userInfo.getDeleteFlag().equals("N"))
 						.forEach(userInfo -> {
 						try {
 							UserInfoRepository uRepo = (UserInfoRepository)BeanUtils.getBean("userInfoRepository");
 							Map<String, Object> sendMap = null;
-							
 							if(status.equalsIgnoreCase("unsubscription")) {
 								// 구독해지 처리.
 								userInfo.setDeleteFlag("Y");
 								userInfo.setDeleteType("unsubscription");
 								uRepo.save(userInfo);
-								
+								logger.info("[해지처리]-["+userInfo.getDonghoInfo().getDonghoId()+"]-[userID = " + userInfo.getId()+"]");
 								// 삭제 이벤트 전송해야...
 								sendMap = kakaoMsgHandler.setKDeleteIdsMsg(dong, ho, userInfo);
+								logger.info("[UNSUBSCRIPTION] - [sendMap] - " + sendMap.toString());
+								
 							}else {
 								if(state.containsKey("colorTemperature") && state.containsKey("brightness")) {
 									body.put("colorDimmer_"+endpointId, state);

+ 72 - 0
src/main/java/com/icontrols/kakao/socket/wallpad/UnlinkExtensionHandler.java

@@ -0,0 +1,72 @@
+package com.icontrols.kakao.socket.wallpad;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.icontrols.kakao.common.utils.BeanUtils;
+import com.icontrols.kakao.entity.DonghoInfo;
+import com.icontrols.kakao.entity.UserInfo;
+import com.icontrols.kakao.repo.DonghoInfoRepository;
+import com.icontrols.kakao.service.AuthService;
+
+public class UnlinkExtensionHandler extends Thread{
+	private static final Logger logger = LoggerFactory.getLogger(UnlinkExtensionHandler.class);
+	private String dong;
+	private String ho;
+	
+	Map<String, Object> subsMap = null;
+	
+	AuthService authService;
+	
+	public UnlinkExtensionHandler(String dong, String ho) {
+		this.dong = dong;
+		this.ho = ho;
+		
+		this.subsMap = new HashMap<String, Object>();
+		this.subsMap.put("type", "unsubs");
+		this.subsMap.put("dong", dong);
+		this.subsMap.put("ho", ho);
+		this.subsMap.put("devNum", "1");
+		this.subsMap.put("company", "kakao");
+		
+	}
+	
+	public void run() {
+		try {
+			logger.info("[UnlinkExtensionHandler] - [START]");
+			DonghoInfoRepository dRepo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
+			List<DonghoInfo> dList = dRepo.findByDongAndHo(this.dong, this.ho);
+			
+			// 해당 동호가 검색되지 않으면 프로세스 종료..
+			if(dList.size() == 0) return;
+			
+			DonghoInfo dInfo = dList.get(0);
+			
+			List<UserInfo> uList = dInfo.getUserInfos();
+			
+			int linkedUserCnt = 0;
+			for(UserInfo userInfo:uList) {
+				if(userInfo.getDeleteFlag().equalsIgnoreCase("N")) linkedUserCnt++;
+			}
+
+			// 아직 해지하지 않은 사용자가 있으면 구독 해지를 날리면 안된다.
+			if(linkedUserCnt > 0) return;
+			
+			
+			// 해당 동호수에 인원이 없을 경우 월패드 구독 해지를 진행해야 한다.
+			authService = (AuthService)BeanUtils.getBean("authServiceImpl");
+			Map<String, Object> retMap = authService.subscriptionProcess(subsMap);
+			
+			logger.info("[해지결과] - [" + dong + "]-[" + ho +"]" + retMap.toString());
+		}catch(Exception e) {
+			logger.error("[UnlinkExtensionHandler] - [ERROR] - " + e.getMessage());
+			e.printStackTrace();
+		}finally {
+			logger.info("[UnlinkExtensionHandler] - [END]");
+		}
+	}
+}

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

@@ -158,7 +158,8 @@ public class WallpadMsgSender {
 			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("      <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());
 		

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

@@ -9,14 +9,14 @@
 
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <fileNamePattern>log/LogFile_%d{yyyy-MM-dd}.log</fileNamePattern>
-            <maxHistory>30</maxHistory>
+            <maxHistory>60</maxHistory>
         </rollingPolicy>
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
             <level>DEBUG</level>
         </filter>
 
         <encoder>
-            <pattern>[DANZI] %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
+            <pattern>[KAKAO] %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
         </encoder>
     </appender>