Преглед изворни кода

Merge branch 'dimming_version' of HomeNetServer/kakao into master

alalssg пре 5 година
родитељ
комит
31eed18f31
23 измењених фајлова са 903 додато и 214 уклоњено
  1. 15 0
      pom.xml
  2. 11 0
      src/main/java/com/icontrols/kakao/KakaoApplication.java
  3. 12 10
      src/main/java/com/icontrols/kakao/common/KAKAO_RESULT.java
  4. 3 0
      src/main/java/com/icontrols/kakao/common/KEY_INFO.java
  5. 53 19
      src/main/java/com/icontrols/kakao/common/SERVERINFO.java
  6. 70 58
      src/main/java/com/icontrols/kakao/common/THINGS_INFO.java
  7. 55 0
      src/main/java/com/icontrols/kakao/common/utils/CommonUtil.java
  8. 0 1
      src/main/java/com/icontrols/kakao/config/AsyncExceptionHandler.java
  9. 180 0
      src/main/java/com/icontrols/kakao/config/DanziSettingConfig.java
  10. 1 1
      src/main/java/com/icontrols/kakao/controller/AuthController.java
  11. 11 8
      src/main/java/com/icontrols/kakao/controller/KakaoDanziController.java
  12. 229 7
      src/main/java/com/icontrols/kakao/controller/MainController.java
  13. 0 3
      src/main/java/com/icontrols/kakao/entity/DonghoInfo.java
  14. 46 0
      src/main/java/com/icontrols/kakao/exceptions/InternalServerError.java
  15. 4 2
      src/main/java/com/icontrols/kakao/service/impl/KakaoExtensionServiceImpl.java
  16. 37 33
      src/main/java/com/icontrols/kakao/socket/wallpad/KakaoEventHandler.java
  17. 65 17
      src/main/java/com/icontrols/kakao/socket/wallpad/KakaoMsgHandler.java
  18. 1 1
      src/main/java/com/icontrols/kakao/socket/wallpad/RecieveiMapMultiSocket.java
  19. 49 47
      src/main/java/com/icontrols/kakao/socket/wallpad/ThreadServerHandler.java
  20. 4 3
      src/main/java/com/icontrols/kakao/socket/wallpad/UnlinkExtensionHandler.java
  21. 1 2
      src/main/java/com/icontrols/kakao/socket/wallpad/WallpadMsgSender.java
  22. 54 0
      src/main/resources/application_setting_info.dat
  23. 2 2
      src/main/resources/logback-spring.xml

+ 15 - 0
pom.xml

@@ -64,6 +64,21 @@
     		<artifactId>mariadb-java-client</artifactId>
     		<version>2.1.0</version>
 		</dependency>
+		<dependency> 
+			<groupId>com.fasterxml.jackson.core</groupId> 
+			<artifactId>jackson-databind</artifactId> 
+			<version>2.9.8</version> 
+		</dependency>
+
+
+		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
+		<dependency>
+		    <groupId>org.projectlombok</groupId>
+		    <artifactId>lombok</artifactId>
+		    <version>1.18.8</version>
+		    <scope>provided</scope>
+		</dependency>
+				
 	</dependencies>
 
 	<build>

+ 11 - 0
src/main/java/com/icontrols/kakao/KakaoApplication.java

@@ -3,6 +3,7 @@ package com.icontrols.kakao;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
+import com.icontrols.kakao.config.DanziSettingConfig;
 import com.icontrols.kakao.socket.wallpad.RecieveiMapMultiSocket;
 
 @SpringBootApplication
@@ -11,6 +12,16 @@ public class KakaoApplication {
 	public static void main(String[] args) {
 		SpringApplication.run(KakaoApplication.class, args);
 		
+		try {
+			new DanziSettingConfig()
+				.getApplicationInfoStr()
+				.setConfigInfo()
+				.setServerInfoALL()
+				.printCurrentServerInfo();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 		// Wallpad에서 전송하는 EventMsg 수신 처리
 		RecieveiMapMultiSocket recieveSocket = new RecieveiMapMultiSocket();
 	}

+ 12 - 10
src/main/java/com/icontrols/kakao/common/KAKAO_RESULT.java

@@ -13,20 +13,22 @@ public class KAKAO_RESULT {
 							FAIL_INVALID_REQ				= -205,
 							FAIL_INVALID_TOKEN				= -206,
 							FAIL_INVALID_CLIENT				= -207,
-							FAIL_UNLINKEXTENSION_SERVICE 	= -208;
+							FAIL_UNLINKEXTENSION_SERVICE 	= -208,
+							FAIL_EXTENSION_SERVICE_TOKEN 	= -209;
 	
 	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_UNLINKEXTENSION_SERVICE(-208, "UnlinkExtensionService","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 인증 실패"),
+		FAIL_EXTENSION_SERVICE_TOKEN(-209, "ExtensionServiceTokenError","확장서비스 토큰 오류");
 		
 		private int resultCode;
 		private String message;

+ 3 - 0
src/main/java/com/icontrols/kakao/common/KEY_INFO.java

@@ -6,6 +6,7 @@ public class KEY_INFO {
 								HTTP_KEY_TYPE 			= "type",
 								HTTP_KEY_AUTHORIZATION 	= "authorization",
 								HTTP_KEY_VERSION 		= "version",
+								HTTP_KEY_METADATA		= "metadata",
 								HTTP_KEY_UNREACHABLEIDS	= "unreachableIds",
 								HTTP_KEY_BODY 			= "body",
 								HTTP_KEY_ERROR 			= "error",
@@ -26,6 +27,8 @@ public class KEY_INFO {
 								BODY_KEY_DISPLAY_TYPE	= "displayType",
 								BODY_KEY_CAPABILITIES	= "capabilities",
 								BODY_KEY_STATE			= "state",
+								BODY_KEY_ADDITIONALPROP	= "additionalProperties",
+								BODY_KEY_ROOMPRESETNAME	= "roomPresetName",
 								BODY_KEY_CAPABILITY_NAME= "capabilityName",
 								BODY_KEY_DESIRED		= "desired"
 								;

+ 53 - 19
src/main/java/com/icontrols/kakao/common/SERVERINFO.java

@@ -1,51 +1,85 @@
 package com.icontrols.kakao.common;
 
 public class SERVERINFO {
-	public static final boolean isDev = false;
+	public static boolean isDev = false;	// beta 앱으로 배포 할때는 무.조.건. true. 아니면 릴리즈 서버와 통신함.
+	public static String danzi_code = "";
+	public static String danzi_info = "";
+	public static String application_version = "";
+	public static String release_version = "";
 	
-	public static final int debugFlag = 1;
+	
+	public static String danziServerExIp = "221.163.243.3";
+	
+	public static int debugFlag = 1;
 	
 	// 월패드 전송 포트 - 신규 프로토콜 적용( 월패드에서 이통사 연동 관련 프로토콜은 기존 수신 소켓이 아닌 독립적인 서비스 수신소켓으로
 	// 실행됨 )
-	public static final int clientNewPort = 10002;
+	public static int clientNewPort = 10002;
 
 	// 월패드에서 수신되는 데이터를 처리 하기 위한 소켓 포트
 //	public static final int WalladReceivePort = 8098;
-	public static final int WalladReceivePort = 2222;
+	public static int WalladReceivePort = 2222;
 
-	public static final String DanjiServerIP = "10.0.1.1";
-	public static final int DanjiServerPort = 10000;
+	public static String DanjiServerIP = "10.0.1.1";
+	public static int DanjiServerPort = 10000;
 
 	// public static final String SendEventIP = "http://61.33.215.56"; // 이통사 개발서버
 	// public static final String SendEventIP = "http://112.220.212.226"; //이통사 상용서버
+	public static String betaKakaoEventDomain = "https://proxy.hdc-smart.com"; // beta용 중계서버로 변경해야함.
+	public static String betaKakaoEventPort = "80";
+	
+//	public static final String releaseKakaoEventDomain = "https://telproxy.hdc-smart.com"; // 배포용 중계서버로 변경해야함.
+	public static String releaseKakaoEventDomain = "https://telproxy.hdc-smart.com"; // 배포용 중계서버로 변경해야함.
+	public static String releaseKakaoEventPort= "80";
 	
-	public static final String SendDevEventURL = "http://localhost"; // 중계서버로 변경해야함.
-	public static final String SendKakaoEventURL = "https://telproxy.hdc-smart.com"; // 중계서버로 변경해야함.
+	public static String SendDevEventURL = "http://localhost"; // 중계서버로 변경해야함.
+	public static String SendKakaoEventURL = isDev?betaKakaoEventDomain+":"+betaKakaoEventPort:releaseKakaoEventDomain+":"+releaseKakaoEventPort;
+//	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";
 
 	public static String SendEventPort = "8005";
-	public static final String SendDevEventPort = "8002";
-	public static final String SendKakaoEventPort = "80";
-
-	public static final String UPDATE_NOTICE_KIND = "/service/new_server.dat";
-	public static final String DEV_SERVER = "/service/dev_server.dat";
+	public static String SendDevEventPort = "8002";
+	public static String SendKakaoEventPort = "80";
+	
+	public static String UPDATE_NOTICE_KIND = "/service/new_server.dat";
+	public static String DEV_SERVER = "/service/dev_server.dat";
 
-	public static final String ONLY_ONE_GAS = "/service/only_one_gas.dat";
-	public static final String WIN_ONLY_ONE_GAS = "C:\\service\\only_one_gas.dat";
+	public static String ONLY_ONE_GAS = "/service/only_one_gas.dat";
+	public static String WIN_ONLY_ONE_GAS = "C:\\service\\only_one_gas.dat";
 
 	public static boolean GasCount_HardCoding_One = false;
 
-	public static final String KAKAO_HEADER_CLIENT_ID = "MPAHXKWELS";
-	public static final String KAKAO_HEADER_CLIENT_SECRET = "SHDPEOWJSKDZALQXLDNS";
+	public static String KAKAO_HEADER_CLIENT_ID_BETA = "PANGWMGNAP";								//beta 앱 client id
+	public static String KAKAO_HEADER_CLIENT_SECRET_BETA = "QWSAZXCDERFVBGTYHNMJ";					//beta 앱 client secret
+	
+	public static String KAKAO_HEADER_CLIENT_ID_RELEASE = "MPAHXKWELS";
+	public static String KAKAO_HEADER_CLIENT_SECRET_RELEASE = "SHDPEOWJSKDZALQXLDNS";
+	
+	public static String KAKAO_HEADER_CLIENT_ID = isDev?KAKAO_HEADER_CLIENT_ID_BETA:KAKAO_HEADER_CLIENT_ID_RELEASE;
+	public static String KAKAO_HEADER_CLIENT_SECRET = isDev?KAKAO_HEADER_CLIENT_SECRET_BETA:KAKAO_HEADER_CLIENT_SECRET_RELEASE;
 	
 //	public static final String KAKAO_EVENT_CLIENT_ID = "pkevk1F4cKHzs7rN4MHe25wYnUm3kRvh";			// beta 앱에서 테스트시
 //	public static final String KAKAO_EVENT_CLIENT_SECRET = "pF2UrvbhkAqbptG4SyrsUU5pTB1DWtqm";		// beta 앱에서 테스트시
 	
-	public static final String KAKAO_EVENT_CLIENT_ID = "zaXpi9VRVobQPFXuSDQzZ3EEdDrgPSUW";			// 릴리즈 앱에서 테스트시
-	public static final String KAKAO_EVENT_CLIENT_SECRET = "Hy5qg31KTSpHnTt8rfZsvFHmAoYTdByp";		// 릴리즈 앱에서 테스트시
+//	public static final String BETA_KAKAO_EVENT_CLIENT_ID = "MULdruZb2xgbDj2jzEk32TSPEBP9dsFN";			// beta 앱에서 테스트시
+//	public static final String BETA_KAKAO_EVENT_CLIENT_SECRET ="RSUBDYEfs36iuGBRm3tR9pDJmTjMphgo";		// beta 앱에서 테스트시
+	
+	public static String BETA_KAKAO_EVENT_CLIENT_ID = "MULdruZb2xgbDj2jzEk32TSPEBP9dsFN";			// beta 앱에서 테스트시
+	public static String BETA_KAKAO_EVENT_CLIENT_SECRET ="RSUBDYEfs36iuGBRm3tR9pDJmTjMphgo";		// beta 앱에서 테스트시
+	
+	public static String RELEASE_KAKAO_EVENT_CLIENT_ID = "zaXpi9VRVobQPFXuSDQzZ3EEdDrgPSUW";			// 릴리즈 앱에서 테스트시
+	public static String RELEASE_KAKAO_EVENT_CLIENT_SECRET = "Hy5qg31KTSpHnTt8rfZsvFHmAoYTdByp";		// 릴리즈 앱에서 테스트시
+	
+	public static String KAKAO_EVENT_CLIENT_ID = isDev?BETA_KAKAO_EVENT_CLIENT_ID:RELEASE_KAKAO_EVENT_CLIENT_ID;
+	public static String KAKAO_EVENT_CLIENT_SECRET = isDev?BETA_KAKAO_EVENT_CLIENT_SECRET:RELEASE_KAKAO_EVENT_CLIENT_SECRET;
+	public static boolean KAKAO_I_WALLPAD_APPLY = false;
+	
+//	public static final String KAKAO_EVENT_CLIENT_ID = "zaXpi9VRVobQPFXuSDQzZ3EEdDrgPSUW";			// 릴리즈 앱에서 테스트시
+//	public static final String KAKAO_EVENT_CLIENT_SECRET = "Hy5qg31KTSpHnTt8rfZsvFHmAoYTdByp";		// 릴리즈 앱에서 테스트시
+	
 	
 	public final static String HEADER_AUTH = "Authorization";
 	

+ 70 - 58
src/main/java/com/icontrols/kakao/common/THINGS_INFO.java

@@ -24,7 +24,7 @@ public final class THINGS_INFO {
 		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\", \"attributes\" : { \"colorTemperature\": { \"min\":3000, \"max\":5700 } } } ]}"),
-		TEMPER("temper", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Temperature\" }, { \"name\" : \"TemperatureSetpoint\" , \"attributes\" : { \"targetSetpoint\": { \"min\":20, \"max\":30 } } } ]}"),
+		TEMPER("temper", "{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"Temperature\" }, { \"name\" : \"TemperatureSetpoint\" , \"attributes\" : { \"targetSetpoint\": { \"min\":8, \"max\":40 } } } ]}"),
 		VENTIL("ventil","{\"capabilities\" : [ { \"name\" : \"Power\" }, { \"name\" : \"AirFlow\" } ]}"),
 		GAS("gas","{\"capabilities\" : [ { \"name\" : \"Lock\" } ] }"),
 		ELEVATOR("elevator", "{\"capabilities\" : [ { \"name\" : \"ElevatorCall\" } ] }"),
@@ -52,62 +52,63 @@ public final class THINGS_INFO {
 	}
 	
 	public enum DEVICE_DETAIL{
-		LIVINGLIGHT					("livinglight", 				"Light", 			"거실조명"),
-		LIGHT01						("light01",						"Light",			"주방조명"),
-		LIGHT02						("light02",						"Light",			"방1조명"),
-		LIGHT03						("light03",						"Light",			"방2조명"),
-		LIGHT04						("light04",						"Light",			"방3조명"),
-		LIGHT05						("light05",						"Light",			"방4조명"),
-		LIGHT06						("light06",						"Light",			"방5조명"),
-		LIGHT07						("light07",						"Light",			"방6조명"),
-		LIGHT08						("light08",						"Light",			"방7조명"),
-		LIGHT09						("light09",						"Light",			"방8조명"),
-		LIGHT10						("light10",						"Light",			"방9조명"),
-		DIMMER_LIVINGLIGHT			("dimmer_livinglight", 			"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조명"),
-		DIMMER_LIGHT06				("dimmer_light06",				"LightDimmer",		"방5조명"),
-		DIMMER_LIGHT07				("dimmer_light07",				"LightDimmer",		"방6조명"),
-		DIMMER_LIGHT08				("dimmer_light08",				"LightDimmer",		"방7조명"),
-		DIMMER_LIGHT09				("dimmer_light09",				"LightDimmer",		"방8조명"),
-		DIMMER_LIGHT10				("dimmer_light10",				"LightDimmer",		"방9조명"),
-		COLOR_DIMMER_LIVINGLIGHT	("colorDimmer_livinglight", 	"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조명"),
-		COLOR_DIMMER_LIGHT06		("colorDimmer_light06",			"ColorLightDimmer",	"방5조명"),
-		COLOR_DIMMER_LIGHT07		("colorDimmer_light07",			"ColorLightDimmer",	"방6조명"),
-		COLOR_DIMMER_LIGHT08		("colorDimmer_light08",			"ColorLightDimmer",	"방7조명"),
-		COLOR_DIMMER_LIGHT09		("colorDimmer_light09",			"ColorLightDimmer",	"방8조명"),
-		COLOR_DIMMER_LIGHT10		("colorDimmer_light10",			"ColorLightDimmer",	"방9조명"),
-		VENTIL						("ventil",						"AirVentilator",	"환기"),
-		GAS							("gas",							"GasValve",			"가스밸브"),
-		ELEVATOR					("elevator",					"ElevatorCaller",	"엘리베이터"),
-		TEMPER1						("temper_1",					"FloorHeater",		"거실난방"),
-		TEMPER2						("temper_2",					"FloorHeater",		"방1난방"),
-		TEMPER3						("temper_3",					"FloorHeater",		"방2난방"),
-		TEMPER4						("temper_4",					"FloorHeater",		"방3난방"),
-		TEMPER5						("temper_5",					"FloorHeater",		"방4난방"),
-		TEMPER6						("temper_6",					"FloorHeater",		"방5난방"),
-		TEMPER7						("temper_7",					"FloorHeater",		"방6난방"),
-		TEMPER8						("temper_8",					"FloorHeater",		"방7난방"),
-		TEMPER9						("temper_9",					"FloorHeater",		"방8난방"),
-		TEMPER10					("temper_10",					"FloorHeater",		"방9난방"),
-		ELECTRIC01					("electric01",					"PowerOutlet",		"거실콘센트"),
-		ELECTRIC02					("electric02",					"PowerOutlet",		"주방콘센트"),
-		ELECTRIC03					("electric03",					"PowerOutlet",		"방1콘센트"),
-		ELECTRIC04					("electric04",					"PowerOutlet",		"방2콘센트"),
-		ELECTRIC05					("electric05",					"PowerOutlet",		"방3콘센트"),
-		ELECTRIC06					("electric06",					"PowerOutlet",		"방4콘센트"),
-		ELECTRIC07					("electric07",					"PowerOutlet",		"방5콘센트"),
-		ELECTRIC08					("electric08",					"PowerOutlet",		"방6콘센트"),
-		ELECTRIC09					("electric09",					"PowerOutlet",		"방7콘센트"),
-		ELECTRIC10					("electric10",					"PowerOutlet",		"방8콘센트")
+		LIVINGLIGHT					("livinglight", 				"Light", 			"거실조명", 	"거실"),
+		LIGHT01						("light01",						"Light",			"주방조명", 	"주방"),
+		LIGHT02						("light02",						"Light",			"안방조명", 	"안방"),
+		LIGHT03						("light03",						"Light",			"방1조명", 	"방1"),
+		LIGHT04						("light04",						"Light",			"방2조명", 	"방2"),
+		LIGHT05						("light05",						"Light",			"방3조명", 	"방3"),
+		LIGHT06						("light06",						"Light",			"방4조명", 	"방4"),
+		LIGHT07						("light07",						"Light",			"방5조명", 	"방5"),
+		LIGHT08						("light08",						"Light",			"방6조명", 	"방6"),
+		LIGHT09						("light09",						"Light",			"방7조명", 	"방7"),
+		LIGHT10						("light10",						"Light",			"방8조명", 	"방8"),
+		DIMMER_LIVINGLIGHT			("dimmer_livinglight", 			"LightDimmer", 		"거실조명", 	"거실"),
+		DIMMER_LIGHT01				("dimmer_light01",				"LightDimmer",		"주방조명", 	"주방"),
+		DIMMER_LIGHT02				("dimmer_light02",				"LightDimmer",		"안방조명", 	"안방"),
+		DIMMER_LIGHT03				("dimmer_light03",				"LightDimmer",		"방1조명", 	"방1"),
+		DIMMER_LIGHT04				("dimmer_light04",				"LightDimmer",		"방2조명", 	"방2"),
+		DIMMER_LIGHT05				("dimmer_light05",				"LightDimmer",		"방3조명", 	"방3"),
+		DIMMER_LIGHT06				("dimmer_light06",				"LightDimmer",		"방4조명", 	"방4"),
+		DIMMER_LIGHT07				("dimmer_light07",				"LightDimmer",		"방5조명", 	"방5"),
+		DIMMER_LIGHT08				("dimmer_light08",				"LightDimmer",		"방6조명", 	"방6"),
+		DIMMER_LIGHT09				("dimmer_light09",				"LightDimmer",		"방7조명", 	"방7"),
+		DIMMER_LIGHT10				("dimmer_light10",				"LightDimmer",		"방8조명", 	"방8"),
+		COLOR_DIMMER_LIVINGLIGHT	("colorDimmer_livinglight", 	"ColorLightDimmer",	"거실조명", 	"거실"),
+		COLOR_DIMMER_LIGHT01		("colorDimmer_light01",			"ColorLightDimmer",	"주방조명", 	"주방"),
+		COLOR_DIMMER_LIGHT02		("colorDimmer_light02",			"ColorLightDimmer",	"안방조명", 	"안방"),
+		COLOR_DIMMER_LIGHT03		("colorDimmer_light03",			"ColorLightDimmer",	"방1조명", 	"방1"),
+		COLOR_DIMMER_LIGHT04		("colorDimmer_light04",			"ColorLightDimmer",	"방2조명", 	"방2"),
+		COLOR_DIMMER_LIGHT05		("colorDimmer_light05",			"ColorLightDimmer",	"방3조명", 	"방3"),
+		COLOR_DIMMER_LIGHT06		("colorDimmer_light06",			"ColorLightDimmer",	"방4조명", 	"방4"),
+		COLOR_DIMMER_LIGHT07		("colorDimmer_light07",			"ColorLightDimmer",	"방5조명", 	"방5"),
+		COLOR_DIMMER_LIGHT08		("colorDimmer_light08",			"ColorLightDimmer",	"방6조명", 	"방6"),
+		COLOR_DIMMER_LIGHT09		("colorDimmer_light09",			"ColorLightDimmer",	"방7조명", 	"방7"),
+		COLOR_DIMMER_LIGHT10		("colorDimmer_light10",			"ColorLightDimmer",	"방8조명", 	"방8"),
+		VENTIL						("ventil",						"AirVentilator",	"환기", 		"거실"),
+		GAS							("gas",							"GasValve",			"가스밸브", 	"주방"),
+		ELEVATOR					("elevator",					"ElevatorCaller",	"엘리베이터",	"공용부"),
+		TEMPER1						("temper_1",					"FloorHeater",		"거실난방",	"거실"),
+		TEMPER2						("temper_2",					"FloorHeater",		"안방난방",	"안방"),
+		TEMPER3						("temper_3",					"FloorHeater",		"방1난방",	"방1"),
+		TEMPER4						("temper_4",					"FloorHeater",		"방2난방",	"방2"),
+		TEMPER5						("temper_5",					"FloorHeater",		"방3난방",	"방3"),
+		TEMPER6						("temper_6",					"FloorHeater",		"방4난방",	"방4"),
+		TEMPER7						("temper_7",					"FloorHeater",		"방5난방",	"방5"),
+		TEMPER8						("temper_8",					"FloorHeater",		"방6난방", 	"방6"),
+		TEMPER9						("temper_9",					"FloorHeater",		"방7난방", 	"방7"),
+		TEMPER10					("temper_10",					"FloorHeater",		"방8난방", 	"방8"),
+		ELECTRIC01					("electric01",					"PowerOutlet",		"거실콘센트", 	"거실"),
+		ELECTRIC02					("electric02",					"PowerOutlet",		"주방콘센트", 	"주방"),
+		ELECTRIC03					("electric03",					"PowerOutlet",		"안방콘센트", 	"안방"),
+		ELECTRIC04					("electric04",					"PowerOutlet",		"방1콘센트", 	"방1"),
+		ELECTRIC05					("electric05",					"PowerOutlet",		"방2콘센트", 	"방2"),
+		ELECTRIC06					("electric06",					"PowerOutlet",		"방3콘센트", 	"방3"),
+		ELECTRIC07					("electric07",					"PowerOutlet",		"방4콘센트", 	"방4"),
+		ELECTRIC08					("electric08",					"PowerOutlet",		"방5콘센트", 	"방5"),
+		ELECTRIC09					("electric09",					"PowerOutlet",		"방6콘센트", 	"방6"),
+		ELECTRIC10					("electric10",					"PowerOutlet",		"방7콘센트", 	"방7"),
+		ELECTRIC11					("electric11",					"PowerOutlet",		"방8콘센트", 	"방8")
 		;
 		
 		
@@ -117,11 +118,13 @@ public final class THINGS_INFO {
 		
 		private String displayName;
 
+		private String roomName;
 		
-		private DEVICE_DETAIL(String modelId, String displayType, String displayName) {
+		private DEVICE_DETAIL(String modelId, String displayType, String displayName, String roomName) {
 			this.modelId = modelId;
 			this.displayType = displayType;
 			this.displayName = displayName;
+			this.roomName = roomName;
 		}
 
 		public String getModelId() {
@@ -147,6 +150,15 @@ public final class THINGS_INFO {
 		public void setDisplayName(String displayName) {
 			this.displayName = displayName;
 		}
+		
+		public String getRoomName() {
+			return roomName;
+		}
+
+		public void setRoomName(String roomName) {
+			this.roomName = roomName;
+		}
+		
 	}
 	
 	public enum THINGS{

+ 55 - 0
src/main/java/com/icontrols/kakao/common/utils/CommonUtil.java

@@ -1,6 +1,8 @@
 package com.icontrols.kakao.common.utils;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Base64;
@@ -11,7 +13,11 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -19,6 +25,8 @@ import com.icontrols.kakao.common.KAKAO_RESULT;
 import com.icontrols.kakao.common.SERVERINFO;
 
 public class CommonUtil {
+	private static final Logger logger = LoggerFactory.getLogger(CommonUtil.class);
+	
 	public static boolean isWindows() {
 		String OS = System.getProperty("os.name").toLowerCase();
 
@@ -139,6 +147,10 @@ public class CommonUtil {
 		// splitStr length 가 2가 아니면 유효하지 않은 authorization 값
 		if(splitStr.length != 2) return KAKAO_RESULT.FAIL_INVALID_CLIENT;
 		
+		logger.info("request   client id = " + splitStr[0]);
+		logger.info("icontrols client id = " + splitStr[1]);
+		logger.info("request   secret = " + SERVERINFO.KAKAO_HEADER_CLIENT_ID);
+		logger.info("icontrols secret = " + SERVERINFO.KAKAO_HEADER_CLIENT_SECRET);
 		if(splitStr[0].equals(SERVERINFO.KAKAO_HEADER_CLIENT_ID) && splitStr[1].equals(SERVERINFO.KAKAO_HEADER_CLIENT_SECRET)) {
 			return KAKAO_RESULT.SUCCESS;
 		}
@@ -163,4 +175,47 @@ public class CommonUtil {
 		
 		return ip;
 	}
+	
+	public static String readFile(String filePath) {
+        BufferedReader br = null;
+        StringBuffer sb = new StringBuffer(); // 테스트용 변수
+         try {
+            br = new BufferedReader(new FileReader(filePath));
+            String line = null;
+            
+            while ((line = br.readLine()) != null) {
+                //System.out.println(line);
+            	// 주석부분은 읽지 않는다.
+            	if(line.length() > 0 && line.charAt(0) == '#') continue;
+                
+            	sb.append(line);
+            }
+ 
+        } catch (IOException ioe) {
+            System.out.println(ioe.getMessage());
+            sb = new StringBuffer();
+        } finally {
+            try { 
+                if (br!=null) 
+                    br.close(); 
+            } catch (Exception e) {}
+        }
+         
+         return sb.toString();
+    }
+	
+	public static String mapToString(Map<String, Object> retMap) {
+		String jsonStr = "";
+		
+		ObjectMapper mapper = new ObjectMapper(); 
+		try { 
+			// convert map to JSON string 
+			jsonStr = mapper.writeValueAsString(retMap); 
+			// compact-print 
+//			jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(retMap); 
+			// pretty-print 
+			} catch (JsonProcessingException e) { e.printStackTrace(); }
+		
+		return jsonStr;
+	}
 }

+ 0 - 1
src/main/java/com/icontrols/kakao/config/AsyncExceptionHandler.java

@@ -19,5 +19,4 @@ public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
         // ...
         System.out.println("==============>>>>>>>>>>>> THREAD ERROR END");
 	}
-
 }

+ 180 - 0
src/main/java/com/icontrols/kakao/config/DanziSettingConfig.java

@@ -0,0 +1,180 @@
+package com.icontrols.kakao.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.icontrols.kakao.common.SERVERINFO;
+import com.icontrols.kakao.common.utils.CommonUtil;
+
+public class DanziSettingConfig {
+	private final Logger logger = LoggerFactory.getLogger(DanziSettingConfig.class);
+	
+	private String filePath;
+	private String fileName;
+	
+	private String applicationInfoStr;
+	private boolean configCompleted = false;
+	private Map<String, String> configInfo;
+	
+	public DanziSettingConfig() {
+		super();
+		logger.info("[단지 설정 클래스 실행]");
+		
+//		filePath = CommonUtil.isWindows()?"D:\\temp\\kakao_bepo\\":"/home/valley/kakao/";
+		filePath = CommonUtil.isWindows()?"D:\\temp\\kakao_bepo\\":"/service/kakao/";
+		fileName = "application_setting_info.dat";
+		configCompleted = true;
+		configInfo = new HashMap<String, String>();
+	}
+	
+	public DanziSettingConfig getApplicationInfoStr() throws Exception{
+		logger.info("[1. 어플리케이션 설정정보 가져오기] - filePath = " + filePath+fileName);
+		
+		applicationInfoStr = CommonUtil.readFile(filePath+fileName).trim();
+		logger.info(applicationInfoStr);
+		
+		if(applicationInfoStr.length() == 0) {
+			logger.error("[1. 어플리케이션 설정정보 가져오기 에러]");
+			configCompleted = false;
+			return this;
+		}
+		return this;
+		
+	}
+	public DanziSettingConfig setConfigInfo() {
+		logger.info("[2. 설정정보 매핑하기]");
+		
+		if(!configCompleted) {
+			logger.error("[DanziSettingConfig ERROR] - setConfigInfo 이전단계 성공하지 않음");
+			return this;
+		}
+		try {
+			String[] infoBuf = applicationInfoStr.split(",");
+			
+			for(String str:infoBuf) {
+				logger.debug("str -> " + str);
+				
+				String key = str.split("=")[0].trim();
+				String val = str.split("=")[1].trim();
+				
+				configInfo.put(key, val);
+			}
+		}catch(Exception e) {
+			logger.error("pDanziSettingConfig ERROR] - setConfigInfo 알수 없는 에러 발생 -" +e.getMessage());
+			configCompleted = false;
+		}
+		
+		return this;
+	}
+	
+	public DanziSettingConfig setServerInfoALL() {
+		logger.info("[3. SERVERINFO.java 값 수정]");
+		if(!configCompleted) {
+			logger.error("[DanziSettingConfig ERROR] - setServerInfo 이전단계 성공하지 않음");
+			return this;
+		}
+		
+		try {
+			String[] infoBuf = applicationInfoStr.split(",");
+			
+			for(String str:infoBuf) {
+				String key = str.split("=")[0].trim();
+				
+				setServerInfo(key);
+			}
+		}catch(Exception e) {
+			logger.error("[DanziSettginConfig ERROR] - setServerInfoALL 알 수 없는 에러 발생 -" + e.getMessage());
+			
+		}
+		
+		return this;
+	}
+	
+	public void setServerInfo(String key) {
+		logger.info("[3. SERVERINFO.java 값 수정 각각]");
+		if(!configCompleted) {
+			logger.error("[DanziSettingConfig ERROR] - setServerInfo 이전단계 성공하지 않음");
+			return;
+		}
+		
+		try{
+			switch(key) {
+				case "aptCode":
+					SERVERINFO.danzi_code = configInfo.get("aptCode");
+					break;
+				case "danziInfo":
+					SERVERINFO.danzi_info = configInfo.get("danziInfo");
+					break;
+				case "settingVersion":
+					SERVERINFO.application_version = configInfo.get("settingVersion");
+					break;
+				case "releaseVersion":
+					SERVERINFO.release_version = configInfo.get("releaseVersion");
+					break;
+				case "danziServerExip":
+					SERVERINFO.danziServerExIp = configInfo.get("danziServerExip");
+					break;
+				case "wallpadSocketPort":
+					SERVERINFO.clientNewPort = Integer.parseInt(configInfo.get("wallpadSocketPort"));
+					break;
+				case "eventSocketPort":
+					SERVERINFO.WalladReceivePort = Integer.parseInt(configInfo.get("eventSocketPort"));
+					break;
+				case "danziServerIP":
+					SERVERINFO.DanjiServerIP = configInfo.get("danziServerIP");
+					break;
+				case "sendKakaoEventURL":
+					SERVERINFO.SendKakaoEventURL = configInfo.get("sendKakaoEventURL");
+					break;
+				case "kakaoHeaderClientId":
+					SERVERINFO.KAKAO_HEADER_CLIENT_ID = configInfo.get("kakaoHeaderClientId");
+					break;
+				case "kakaoHeaderClientSecret":
+					SERVERINFO.KAKAO_HEADER_CLIENT_SECRET = configInfo.get("kakaoHeaderClientSecret");
+					break;
+				case "kakaoEventClientId":
+					SERVERINFO.KAKAO_EVENT_CLIENT_ID = configInfo.get("kakaoEventClientId");
+					break;
+				case "kakaoEventClientSecret":
+					SERVERINFO.KAKAO_EVENT_CLIENT_SECRET = configInfo.get("kakaoEventClientSecret");
+					break;
+				case "kakaoIWallpadAccess" :
+					SERVERINFO.KAKAO_I_WALLPAD_APPLY = configInfo.get("kakaoIWallpadAccess").equalsIgnoreCase("true")?true:false;
+					break;
+					
+				default:
+					logger.error("[DanziSettingConfig ERROR] - 해당 키 없음 -" + key);
+			}
+		}catch(Exception e) {
+			logger.error("[DanziSettginConfig ERROR] - setServerInfo 알 수 없는 에러 발생 -" + e.getMessage());
+		}
+	}
+	
+	public Map<String, String> getConfigInfo(){
+		return configInfo;
+	}
+	
+	public boolean getConfigCompleted() {
+		return configCompleted;
+	}
+	
+	public void printCurrentServerInfo() {
+		logger.info("[SERVERINFO.danzi_code] - " 			+ SERVERINFO.danzi_code
+		+ "\r\n[SERVERINFO.danzi_info] - " 					+ SERVERINFO.danzi_info
+		+ "\r\n[SERVERINFO.application_version] - " 		+ SERVERINFO.application_version
+		+ "\r\n[SERVERINFO.release_version] - " 			+ SERVERINFO.release_version
+		+ "\r\n[SERVERINFO.danziServerExIp] - " 			+ SERVERINFO.danziServerExIp
+		+ "\r\n[SERVERINFO.clientNewPort] - " 				+ SERVERINFO.clientNewPort
+		+ "\r\n[SERVERINFO.WalladReceivePort] - " 			+ SERVERINFO.WalladReceivePort
+		+ "\r\n[SERVERINFO.DanjiServerIP] - " 				+ SERVERINFO.DanjiServerIP
+		+ "\r\n[SERVERINFO.SendKakaoEventURL] - " 			+ SERVERINFO.SendKakaoEventURL
+		+ "\r\n[SERVERINFO.KAKAO_HEADER_CLIENT_ID] - " 		+ SERVERINFO.KAKAO_HEADER_CLIENT_ID
+		+ "\r\n[SERVERINFO.KAKAO_HEADER_CLIENT_SECRET] - " 	+ SERVERINFO.KAKAO_HEADER_CLIENT_SECRET
+		+ "\r\n[SERVERINFO.KAKAO_EVENT_CLIENT_ID] - " 		+ SERVERINFO.KAKAO_EVENT_CLIENT_ID
+		+ "\r\n[SERVERINFO.KAKAO_EVENT_CLIENT_SECRET] - " 	+ SERVERINFO.KAKAO_EVENT_CLIENT_SECRET);
+	}
+	
+}

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

@@ -77,7 +77,7 @@ public class AuthController {
 		}
 		
 		
-		logger.info("kakao test --<>>>>> --> " + thingsRepo.count());
+//		logger.info("kakao test --<>>>>> --> " + thingsRepo.count());
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		
 		

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

@@ -70,22 +70,25 @@ public class KakaoDanziController {
 			
 			if(reqType.equals(TYPE.REQ_TYPE.GRANTAUTH.getTypeName())) {
 				// grantauth 인 경우에만 헤더의 인증 필드를 검증한다.
-				
 				if(!header.containsKey(SERVERINFO.HEADER_AUTH)) {
+					params.remove(KEY_INFO.HTTP_KEY_BODY);
 					params.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INVALID_CLIENT));
-					return params;
+					retMap = params;
 				}else {
 					String authorization =  request.getHeader(SERVERINFO.HEADER_AUTH);
 					logger.info("[Authorization] - "+authorization);
 					int validation_auth = CommonUtil.validateHeaderAuth(authorization);
 					if(validation_auth != KAKAO_RESULT.SUCCESS) {
+						params.remove(KEY_INFO.HTTP_KEY_BODY);
 						params.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INVALID_CLIENT));
-						return params;
+						logger.error("[Authorization ERROR - ] - ["+authorization+"] - " + KAKAO_RESULT.FAIL_INVALID_CLIENT);
+						retMap = params;
+					}else {
+						// 카카오 홈과 유저의 인증 완료시 카카오에서 전송해주는 API TYPE
+						// 건내받은 토큰 정보를 DB에 저장해야 한다.
+						retMap = kakaoService.request_grantAuthorization(params);
 					}
 				}
-				// 카카오 홈과 유저의 인증 완료시 카카오에서 전송해주는 API TYPE
-				// 건내받은 토큰 정보를 DB에 저장해야 한다.
-				retMap = kakaoService.request_grantAuthorization(params);
 			} else if(reqType.equals(TYPE.REQ_TYPE.DISCOVER.getTypeName())) {
 				// 월패드와 연결된 기기목록들을 요청하는 API TYPE
 				retMap = kakaoService.request_discover(params);
@@ -104,14 +107,14 @@ public class KakaoDanziController {
 			}
 		}catch(Exception e) {
 			logger.error("[Unknown ERROR]" + e.getMessage());
+			logger.error(e.getStackTrace().toString());
 			e.printStackTrace();
 			retMap = KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL);
 		}finally {
 			retMap.remove(KEY_INFO.HTTP_KEY_AUTHORIZATION);
 		}
 		
-		logger.info("[RESULT] - " + retMap.toString());
-		
+		logger.info("[RESULT] - " + CommonUtil.mapToString(retMap));
 		return retMap;
 	}
 }

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

@@ -43,6 +43,205 @@ public class MainController {
 	@Autowired
 	KakaoExtensionService service;
 	
+	String[] dongho_arr = {
+			"3124/403",
+			"3123/2605",
+			"3122/405",
+			"3124/2602",
+			"3124/403",
+			"3121/705",
+			"3123/2204",
+			"3126/203",
+			"3124/2503",
+			"3126/2002",
+			"3122/605",
+			"3126/203",
+			"3123/1003",
+			"3123/1005",
+			"3124/2303",
+			"3122/2001",
+			"3123/2404",
+			"3124/705",
+			"3125/1605",
+			"3121/205",
+			"3126/1305",
+			"3124/2601",
+			"3125/2303",
+			"3124/1403",
+			"3121/1005",
+			"3126/302",
+			"3126/305",
+			"3122/1404",
+			"3126/2203",
+			"3122/205",
+			"3124/302",
+			"3124/2501",
+			"3123/1105",
+			"3124/1303",
+			"3125/2303",
+			"3123/2204",
+			"3123/401",
+			"3122/805",
+			"3122/2205",
+			"3123/1903",
+			"3124/804",
+			"3122/1101",
+			"3126/405",
+			"3124/1001",
+			"3124/1602",
+			"3122/2001",
+			"3125/1603",
+			"3121/1001",
+			"3121/1702",
+			"3123/1401",
+			"3123/1401",
+			"3124/1501",
+			"3124/1501",
+			"3124/804",
+			"3126/1103",
+			"3126/105",
+			"3123/1402",
+			"3123/1401",
+			"3122/1901",
+			"3121/203",
+			"3123/1401",
+			"3121/1701",
+			"3126/1705",
+			"3125/1101",
+			"3125/1101",
+			"3121/203",
+			"3124/101",
+			"3123/1105",
+			"3123/2505",
+			"3126/302",
+			"3121/1603",
+			"3123/2704",
+			"3125/1202",
+			"3123/1901",
+			"3123/1901",
+			"3126/2101",
+			"3126/2603",
+			"3126/2604",
+			"3126/2604",
+			"3126/2604",
+			"3123/2603",
+			"3126/1502",
+			"3122/201",
+			"3126/305",
+			"3122/901",
+			"3126/1201",
+			"3124/2903",
+			"3123/2705",
+			"3123/2705",
+			"3121/1601",
+			"3123/2705",
+			"3124/1602",
+			"3125/1605",
+			"3124/1603",
+			"3122/2305",
+			"3123/804",
+			"3125/2403",
+			"3123/804",
+			"3126/902",
+			"3126/902",
+			"3125/2203",
+			"3122/1902",
+			"3123/305",
+			"3122/805",
+			"3126/1004",
+			"3123/2405",
+			"3123/1102",
+			"3126/2402",
+			"3125/1202",
+			"3125/2804",
+			"3123/2905",
+			"3122/1202",
+			"3126/1002",
+			"3126/1704",
+			"3123/403",
+			"3122/905",
+			"3126/1902",
+			"3123/1504",
+			"3125/2102",
+			"3121/901",
+			"3126/502",
+			"3124/1802",
+			"3125/2203",
+			"3121/1801",
+			"3123/1604",
+			"3124/2501",
+			"3125/1703",
+			"3125/1703",
+			"3122/101",
+			"3123/1902",
+			"3126/1704",
+			"3126/1704",
+			"3125/2402",
+			"3125/1703",
+			"3126/1401",
+			"3126/1401",
+			"3126/1401",
+			"3123/2705",
+			"3123/1902",
+			"3126/2202",
+			"3125/102",
+			"3123/305",
+			"3123/803",
+			"3125/903",
+			"3125/902",
+			"3125/1504",
+			"3123/904",
+			"3126/1204",
+			"3126/1204",
+			"3122/1003",
+			"3122/2205",
+			"3122/803",
+			"3125/2404",
+			"3126/303",
+			"3123/503",
+			"3126/2001",
+			"3124/1502",
+			"3122/705",
+			"3124/702",
+			"3122/101",
+			"3126/705",
+			"3121/2201",
+			"3124/1703",
+			"3123/1504",
+			"3124/1703",
+			"3123/503",
+			"3126/104",
+			"3126/104",
+			"3124/301",
+			"3123/1601",
+			"3125/2105",
+			"3125/805",
+			"3121/1305",
+			"3126/2905",
+			"3123/1805",
+			"3123/1805",
+			"3125/2105",
+			"3123/1103",
+			"3121/2202",
+			"3126/903",
+			"3123/2405",
+			"3123/1103",
+			"3125/2301",
+			"3121/1001",
+			"3121/2202",
+			"3125/2105",
+			"3126/301",
+			"3125/402",
+			"3123/1601",
+			"3123/1601",
+			"3126/1403",
+			"3126/2203",
+			"3125/402",
+			"3125/303",
+			"3123/1205",
+			"3122/2004"	
+	};
+	
 	@RequestMapping(value = "/test", method = RequestMethod.POST, consumes = "application/json")
 	public @ResponseBody Map<String, Object> recieveTest(@RequestHeader HttpHeaders header,
 														@RequestBody Map<String, Object> params,
@@ -54,7 +253,8 @@ public class MainController {
 		logger.info("==========================================이벤트 수신=================================");
 		logger.info("===================================================================================");
 		logger.info("body :" + header);
-
+		
+		
 //		Map<String,Object> retMap = new HashMap<String, Object>();
 //		
 //		retMap.put(KEY_INFO.HTTP_KEY_ID, params.get(KEY_INFO.HTTP_KEY_ID));
@@ -163,13 +363,35 @@ public class MainController {
 			
 			int devNum = Integer.parseInt((String)param.get("devNum"));
 		 */
-		Map<String,Object> retMap = new HashMap<String, Object>();
-		authService.subscriptionProcess(params);
 		
-		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));
 		
-		return retMap;
+//		Map<String,Object> retMap = new HashMap<String, Object>();
+//		authService.subscriptionProcess(params);
+//		
+//		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));
+		
+		for(String dongho:dongho_arr) {
+			Map<String, Object> subsMap = new HashMap<String, Object>();
+			
+			subsMap.put("type", "subs");
+			subsMap.put("dong", dongho.split("/")[0]);
+			subsMap.put("ho", dongho.split("/")[1]);
+			subsMap.put("devNum", "1");
+			subsMap.put("company", "kakao");
+			
+			// 구독 신청
+			authService.subscriptionProcess(subsMap);
+			
+			// 모바일 기기 등록
+			authService.remoteRegisterNewDevice(subsMap);
+			
+			logger.info("["+subsMap.get("dong")+"]-["+subsMap.get("ho")+"] - 완료");
+		}
+		
+		
+		
+		return null;
 	}
 }

+ 0 - 3
src/main/java/com/icontrols/kakao/entity/DonghoInfo.java

@@ -75,7 +75,4 @@ public class DonghoInfo implements Serializable{
 	public void setUserInfos(List<UserInfo> userInfos) {
 		this.userInfos = userInfos;
 	}
-	
-
-
 }

+ 46 - 0
src/main/java/com/icontrols/kakao/exceptions/InternalServerError.java

@@ -0,0 +1,46 @@
+package com.icontrols.kakao.exceptions;
+
+public class InternalServerError extends Exception {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 5666795755492770040L;
+	private String errorCode;
+	private String errorMessage;
+	
+	public InternalServerError() {
+		super();
+		// TODO Auto-generated constructor stub
+	}
+	
+	public InternalServerError(String errorCode, String errorMessage) {
+		super(errorMessage);
+		this.errorCode = errorCode;
+		this.errorMessage = errorMessage;
+	}
+
+	public InternalServerError(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+		// TODO Auto-generated constructor stub
+	}
+	public InternalServerError(String message, Throwable cause) {
+		super(message, cause);
+		// TODO Auto-generated constructor stub
+	}
+	public InternalServerError(String message) {
+		super(message);
+		// TODO Auto-generated constructor stub
+	}
+	public InternalServerError(Throwable cause) {
+		super(cause);
+		// TODO Auto-generated constructor stub
+	}
+
+	public String getErrorCode() {
+		return errorCode;
+	}
+
+	public String getErrorMessage() {
+		return errorMessage;
+	}
+}

+ 4 - 2
src/main/java/com/icontrols/kakao/service/impl/KakaoExtensionServiceImpl.java

@@ -105,19 +105,21 @@ public class KakaoExtensionServiceImpl implements KakaoExtensionService {
 			
 			// 기기목록 조회 및 저장
 			List<ThingsInfo> databaseThingsList = thingsInfoRepository.findByDongAndHo(dong_ho.split("/")[0], dong_ho.split("/")[1]);
+			List<ThingsInfo> wallpadThingsList = kMsgHandler.getConnectDevices(dong, ho);
 			
 			if(databaseThingsList.size() == 0) {
-				List<ThingsInfo> wallpadThingsList = kMsgHandler.getConnectDevices(dong, ho);
 				
 				if(wallpadThingsList == null) {
 					logger.error("[Auth Database Insert Error]");
 					param.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
 					return param;
+				}else {
+					thingsInfoRepository.saveAll(wallpadThingsList);
 				}
 				
-				thingsInfoRepository.saveAll(wallpadThingsList);
 			}
 			
+			
 			userInfo.setKakaoAccessToken((String) body.get(KEY_INFO.BODY_KEY_ACCESS_TOKEN));
 			userInfo.setKakaoRefreshToken((String) body.get(KEY_INFO.BODY_KEY_REFRESH_TOKEN));
 			userInfo.setKakaoExpiresTime(Integer.toString((int)body.get(KEY_INFO.BODY_KEY_EXPIRES_IN)));

+ 37 - 33
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoEventHandler.java

@@ -64,22 +64,20 @@ public class KakaoEventHandler {
 			
 			int result = CommonUtil.compareStringTypeTime(currentTime, tokenExpiresTime);
 			
-//			boolean connFlag = true;
+			//boolean connFlag = true;
 			// 현재 시간이 토큰 만료시간보다 크다면 토큰이 만료 됐다는 뜻.
 			// 카카오 이벤트 서버에서 토큰을 갱신 받은 뒤 이벤트를 전송해야 한다.
-			if(result < 1) {
-				userInfo = sendKakaoTokenRefresh(userInfo);
-
-				if(userInfo == null) {
-					retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
-					retMap.put("message", "ID-["+userInfo.getId() + "]-Fail to Token Refresh");
-					return CompletableFuture.completedFuture(retMap);
-				}
-				
-				logger.info("prev donghoInfo : " + userInfo.toString());
-				
-				params.put(KEY_INFO.HTTP_KEY_AUTHORIZATION, userInfo.getKakaoAccessToken());
-			}
+//			if(result < 1) {
+//				userInfo = sendKakaoTokenRefresh(userInfo);
+//
+//				if(userInfo == null) {
+//					retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
+//					retMap.put("message", "ID-["+userInfo.getId() + "]-Fail to Token Refresh");
+//					return CompletableFuture.completedFuture(retMap);
+//				}
+//				
+//				params.put(KEY_INFO.HTTP_KEY_AUTHORIZATION, userInfo.getKakaoAccessToken());
+//			}
 			
 			logger.debug("["+userInfo.getKakaoAccessToken()+"] - 유효한 토큰");
 			
@@ -87,13 +85,23 @@ public class KakaoEventHandler {
 			Map<String, Object> sendResult = sendStatusResult(userInfo, params);
 			
 			int code = (int) sendResult.get("result");
-			logger.info("[EVENT RESULT] - ["+code+"]");
+			logger.debug("[EVENT RESULT] - ["+code+"]");
 			UserInfoRepository repo = null;
 			switch(code) {
 			case KAKAO_RESULT.FAIL_INTERNAL:
 				break;
+			case KAKAO_RESULT.FAIL_EXTENSION_SERVICE_TOKEN: //확장서비스 토큰 에러
+				logger.error("["+userInfo.getKakaoAccessToken()+"] - 확장서비스 토큰 에러..삭제요청");
+				repo = (UserInfoRepository)BeanUtils.getBean("userInfoRepository");
+				userInfo.setDeleteFlag("Y");
+				userInfo.setDeleteType(CODE.FAIL_INVALID_TOKEN.getMessage());
+				repo.save(userInfo);
+				
+				retMap.put("result", KAKAO_RESULT.FAIL_INTERNAL);
+				retMap.put("message", "ID-["+userInfo.getId() + "]-FAIL_EXTENSION_SERVICE_TOKEN");
+				break;
 			case KAKAO_RESULT.FAIL_INVALID_TOKEN: // 유효하지 않은 토큰, 연동 해제한 계정 토큰
-				logger.info("["+userInfo.getKakaoAccessToken()+"] - 유효하지 않은 토큰..삭제요청");
+				logger.error("[" + userInfo.getId() + "]-["+userInfo.getKakaoAccessToken()+"] - 유효하지 않은 토큰..삭제요청");
 				repo = (UserInfoRepository)BeanUtils.getBean("userInfoRepository");
 				userInfo.setDeleteFlag("Y");
 				userInfo.setDeleteType(CODE.FAIL_INVALID_TOKEN.getMessage());
@@ -103,7 +111,7 @@ public class KakaoEventHandler {
 				retMap.put("message", "ID-["+userInfo.getId() + "]-FAIL_INVALID_TOKEN");
 				break;
 			case KAKAO_RESULT.FAIL_UNLINKEXTENSION_SERVICE: // 서비스를 해지한 경우
-				logger.info("["+userInfo.getKakaoAccessToken()+"] - 서비스 해제 토근..삭제요청");
+				logger.error("["+userInfo.getKakaoAccessToken()+"] - 서비스 해제 토근..삭제요청");
 				repo = (UserInfoRepository)BeanUtils.getBean("userInfoRepository");
 				userInfo.setDeleteFlag("Y");
 				userInfo.setDeleteType(CODE.FAIL_UNLINKEXTENSION_SERVICE.getMessage());
@@ -176,17 +184,20 @@ public class KakaoEventHandler {
 				logger.error("[sendStatusResult] - params is null");
 				return retMap;
 			}
-			logger.info("[sendStatusResult] - START - " + userInfo.toString());
+			logger.info("[sendStatusResult] - START - " + CommonUtil.mapToString(params));
 			
 			String authorization = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
 			String encoding = Base64.getEncoder().encodeToString(authorization.getBytes());
+
+			//			logger.info("autho = " + authorization);
+			//			logger.info("encoding = " + encoding);
 			
 			CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
 			HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
 			
 			requestFactory.setHttpClient(httpClient);
-			requestFactory.setConnectTimeout(3000);
-			
+			requestFactory.setConnectTimeout(10000);
+			requestFactory.setReadTimeout(10000);
 			RestTemplate restTemplate = new RestTemplate(requestFactory);
 
 			HttpHeaders headers = new HttpHeaders();
@@ -196,11 +207,12 @@ public class KakaoEventHandler {
 			// 제어기기 별로 상태 이벤트 구분하여 처리하도록 해야 한다
 			HttpEntity<Object> entity = new HttpEntity<Object>(params, headers);
 			
-			String url = SERVERINFO.isDev?SERVERINFO.SendDevEventURL + ":" + SERVERINFO.SendDevEventPort + "/events":SERVERINFO.SendKakaoEventURL + ":" + SERVERINFO.SendKakaoEventPort + "/events";
+			String url = SERVERINFO.SendKakaoEventURL + "/events";
 
 			logger.debug("SendStatusResult URL : " + url);
 			logger.debug("SendStatusResult header :  " + headers.toString());
 			logger.debug("SendStatusResult return value : " + params.toString());
+			logger.info("sendStatusResult entity : " + entity.toString());
 			String answer = restTemplate.postForObject(url, entity, String.class);
 			
 			logger.info("SendStatusResult answer :" + answer);
@@ -248,7 +260,6 @@ public class KakaoEventHandler {
 		String authorization = SERVERINFO.KAKAO_EVENT_CLIENT_ID+":"+SERVERINFO.KAKAO_EVENT_CLIENT_SECRET;
 		String encoding = Base64.getEncoder().encodeToString(authorization.getBytes());
 		
-		
 		HttpHeaders headers = new HttpHeaders();
 		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
 		headers.add("Authorization", "Basic " + encoding);
@@ -259,7 +270,7 @@ 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 = SERVERINFO.SendKakaoEventURL +"/events/token";
 		
 //		String url = "https://kakaohome-api.i.kakao.com/events/token";
 		logger.debug("[TOKEN REFRESH REQUEST] URL : " + url);
@@ -272,7 +283,8 @@ public class KakaoEventHandler {
 		HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
 		
 		requestFactory.setHttpClient(httpClient);
-		requestFactory.setConnectTimeout(3000);
+		requestFactory.setConnectTimeout(10000);
+		requestFactory.setReadTimeout(10000);
 
 		String answer = "";
 		try {
@@ -296,18 +308,10 @@ public class KakaoEventHandler {
 				return userInfo;
 			}
 		}catch(Exception e) {
-			
-			if( e != null) {
 				logger.error("[TOKEN REFRESH REQUEST ERROR] - " + e.getMessage());
-			
 				e.printStackTrace();
-			}else
-				logger.error("Token REFRESH REQUEST ERROR]");
 		}
-		
-		logger.error("****************************************************");
-		logger.error("토클 리프레시 실패");
-		logger.error("****************************************************");
+		logger.error("토클 리프레시 실패" + userInfo.getDonghoInfo().getDong() + "_" + userInfo.getDonghoInfo().getHo());
 		
 		return null;
 	}

+ 65 - 17
src/main/java/com/icontrols/kakao/socket/wallpad/KakaoMsgHandler.java

@@ -22,6 +22,7 @@ import org.w3c.dom.NodeList;
 import com.icontrols.kakao.common.ERROR_INFO;
 import com.icontrols.kakao.common.KAKAO_RESULT;
 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.utils.BeanUtils;
@@ -40,7 +41,8 @@ import com.icontrols.kakao.socket.utils.XMLGenerator;
 @Service("kakaoMsgHandler")
 public class KakaoMsgHandler {
 	private final static Logger logger = LoggerFactory.getLogger(KakaoMsgHandler.class);
-	
+	private static final int 	REQ_TYPE_QUERY = 1;
+	private static final int REQ_TYPE_UPDATE = 2;
 	@Resource(name="asyncConfig")
 	private AsyncConfig asyncConfig;
 	
@@ -72,7 +74,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.info("[doAuthProcess]-[인증번호요청] - [" + dong + "동]-[" + ho + "호] - [" + code + " ]");
 			
 			String rcvMsg = SSLClient.sendToWallpad(targetIP, sb.toString());
 			
@@ -132,7 +134,7 @@ public class KakaoMsgHandler {
 			.append("      <device_info alias=\"").append(alias).append("\" twinid=\"").append(twinid).append("\"  />\r\n")
 			.append(XMLGenerator.MakeXMLTail());
 			
-			logger.info(sb.toString());
+			logger.info("[remoteRegisterNewDevice] - [구독요청] - [" + dong + "동]-["+ho+"호]-["+twinid+"]");
 			
 			SSLClient.sendToWallpad(targetIP, sb.toString());
 			
@@ -164,7 +166,7 @@ public class KakaoMsgHandler {
 			logger.debug("[KakaoMsgHandler - getConnectDevices] - xmlResult -> " + xmlResult);
 			
 			if(!xmlResult.equalsIgnoreCase("ok")) {
-				logger.error("[KakaoMsgHandler - getConnectDevices] xmlResult not ok");
+				logger.error("[KakaoMsgHandler - getConnectDevices] xmlResult not ok \r\n" + xmlResult);
 				return null;
 			}
 			
@@ -195,7 +197,6 @@ public class KakaoMsgHandler {
 							}else {
 								NodeList childList = (NodeList)xpath.evaluate("//imap/service/devinfo/*[@name='"+ tmpModelId +"']", doc, XPathConstants.NODESET);
 								thingList.addAll(getChildThingsInfoList(dong, ho, childCount, childList));
-								
 							}
 						}catch(Exception e) {
 							logger.error("[ERROR] at stream - " + e.getMessage());
@@ -221,6 +222,7 @@ public class KakaoMsgHandler {
 	
 	public Map<String, Object> getDevicesStatusList(int dong, int ho) {
 		Map<String, Object> retMap = new HashMap<String, Object>();
+		Map<String, String> metadata = new HashMap<String, String>();
 		Map<String, Object> body = new HashMap<String, Object>();
 		List<String> unreachableIds = new ArrayList<String>();
 		
@@ -241,7 +243,8 @@ public class KakaoMsgHandler {
 			
 			if(!xmlResult.equalsIgnoreCase("ok")) {
 				retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_UNREACHABLE));
-				logger.error("[KakaoMsgHandler - getDeviceList] xmlResult not ok");
+				logger.error("[KakaoMsgHandler - getDeviceList] xmlResult not ok \r\n" + xmlResult);
+				
 				return retMap;
 			}
 			
@@ -313,19 +316,34 @@ public class KakaoMsgHandler {
 			// elevator가 존재해야 카카오홈 앱에서 엘리베이터를 제어할 수 있다.
 			Map<String, Object> eleMap = new HashMap<String, Object>();
 			
-			eleMap.put("displayType", THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
+			eleMap.put(KEY_INFO.BODY_KEY_DISPLAY_TYPE, THINGS_INFO.THINGS.ELEVATOR.getKakaoDisplayName());
 			eleMap.putAll(getDeviceCapabilities(THINGS_INFO.THINGS.ELEVATOR.getThingsName(), null));
-			eleMap.put("endpointId", THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getModelId());
-			eleMap.put("name", THINGS_INFO.THINGS.ELEVATOR.getDesc());
-			eleMap.put("state", new HashMap<String, Object>());
-			
+			eleMap.put(KEY_INFO.BODY_KEY_ENDPOINT_ID, THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getModelId());
+			eleMap.put(KEY_INFO.BODY_KEY_NAME, THINGS_INFO.THINGS.ELEVATOR.getDesc());
+			eleMap.put(KEY_INFO.BODY_KEY_STATE, new HashMap<String, Object>());
+			eleMap.put(KEY_INFO.BODY_KEY_ADDITIONALPROP, getAdditionalProp(KEY_INFO.BODY_KEY_ROOMPRESETNAME, THINGS_INFO.DEVICE_DETAIL.ELEVATOR.getRoomName()));
 			body.put("elevator", eleMap);
 			
+			if(SERVERINFO.KAKAO_I_WALLPAD_APPLY) {
+				Map<String, Object> wpMap = new HashMap<String, Object>();
+				String wpEndpointId = "WALLPAD_"+SERVERINFO.danzi_code+"_"+dong+"_"+ho;
+				wpMap.put("endpointId", wpEndpointId);
+				wpMap.put("name", "월패드");
+				wpMap.put("displayType", "DummyWallPad");
+				wpMap.put("capabilities", new ArrayList<>());
+				wpMap.put("state", "{}");
+				wpMap.put("additionalProperties", null);
+				
+				body.put(wpEndpointId, wpMap);
+			}
+			
 		}catch(Exception e) {
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
 			logger.error("[ERROR] - " + e.getMessage());
 		}
 		
+		metadata.put("aptCode", SERVERINFO.danzi_code);
+		retMap.put(KEY_INFO.HTTP_KEY_METADATA, metadata); 
 		retMap.put(KEY_INFO.HTTP_KEY_UNREACHABLEIDS, unreachableIds);
 		retMap.put(KEY_INFO.HTTP_KEY_BODY, body);
 		
@@ -379,7 +397,7 @@ public class KakaoMsgHandler {
 			return retMap;
 		}
 		
-		return getStatusMap(endpointId, doc);
+		return getStatusMap(endpointId, doc, REQ_TYPE_QUERY, dong, ho);
 	}
 	
 	/**
@@ -403,6 +421,7 @@ public class KakaoMsgHandler {
 		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;
 		}
 		
@@ -440,7 +459,7 @@ public class KakaoMsgHandler {
 			return retMap;
 		}
 		
-		return getStatusMap(endpointId, doc);
+		return getStatusMap(endpointId, doc, REQ_TYPE_UPDATE, dong, ho);
 	}
 	
 	/**
@@ -449,30 +468,52 @@ public class KakaoMsgHandler {
 	 * @param doc
 	 * @return
 	 */
-	public static Map<String, Object> getStatusMap(String endpointId, Document doc){
+	public static Map<String, Object> getStatusMap(String endpointId, Document doc, int req_type, int dong, int ho){
 		Map<String, Object> retMap = new HashMap<String, Object>();
 		
 		XPath xpath = XPathFactory.newInstance().newXPath();
+		String status = "";
 		try {
 			Node iMap = (Node) xpath.evaluate("//imap/service", doc, XPathConstants.NODE);
 			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)); 
-				logger.error("[ERROR]-[xmlResult is not ok");
+				logger.error("[ERROR]-[xmlResult is not ok \r\n" + xmlResult);
 				return retMap;
 			}
 			
-			String status = (String) xpath.evaluate("//imap/service/status", doc, XPathConstants.STRING);
+			status = (String) xpath.evaluate("//imap/service/status", doc, XPathConstants.STRING);
 			
 			Map<String, Object> state = setDeviceState(endpointId, status);
 			retMap.put(endpointId, state);
 			
+		
 		} catch (XPathExpressionException e) {
 			retMap.put(KEY_INFO.HTTP_KEY_ERROR, KAKAO_RESULT.getErrorInfo(KAKAO_RESULT.FAIL_INTERNAL));
 			e.printStackTrace();
 		}
 		
+		if(req_type == REQ_TYPE_UPDATE) {
+			try {
+				String logMessage = "";
+				if(endpointId.equalsIgnoreCase("elevator")) {
+					logMessage = "[KAKAO Device Result] ip: " + SERVERINFO.danziServerExIp + " dong: " + dong + "  ho: " + ho + " model_id: elevator dev_num: 1 status: down";
+				}else {
+					// 기기정보를 알아와요
+					String arrEndpointId[]  = endpointId.split("_");
+					
+					String str_modelId = arrEndpointId[arrEndpointId.length-2]; 
+					String str_devNum = arrEndpointId[arrEndpointId.length-1]; 
+					
+					logMessage = "[KAKAO Device Result] ip: "+ SERVERINFO.danziServerExIp +" dong: "+ dong + "ho: " + ho + " model_id: " + str_modelId + " dev_num: " + str_devNum + " status: " + status;
+				}
+				logger.info(logMessage);
+			}catch(Exception e) {
+				logger.error("[ELK Log Parsing Error] - " + endpointId + " status = " + status + "\r\n" + e.getMessage());
+			}
+		}
+		
 		logger.debug("[UPDATE RESULT] - " + retMap.toString());
 		return retMap;
 	}
@@ -572,6 +613,11 @@ public class KakaoMsgHandler {
 		return capabilities;
 	}
 	
+	public Map<String, Object> getAdditionalProp(String key, String value){
+		Map<String, Object> additionalPropMap = new HashMap<String, Object>();
+		additionalPropMap.put(key, value);
+		return additionalPropMap;
+	}
 	public List<ThingsInfo> getChildThingsInfoList(int dong, int ho, int childCount, NodeList childList) {
 		List<ThingsInfo> thingsList = new ArrayList<>();
 		
@@ -671,6 +717,7 @@ public class KakaoMsgHandler {
 			    		
 			    		deviceInfo.putAll(getDeviceCapabilities(endpointId, status));
 			    		deviceInfo.put(KEY_INFO.BODY_KEY_STATE, setDeviceState(endpointId, status));
+			    		deviceInfo.put(KEY_INFO.BODY_KEY_ADDITIONALPROP, getAdditionalProp(KEY_INFO.BODY_KEY_ROOMPRESETNAME,  detailDev.getRoomName()));
 			    		
 			    		deviceMap.put(endpointId, deviceInfo);
 			    		deviceList.add(deviceMap);
@@ -945,7 +992,8 @@ public class KakaoMsgHandler {
 		case THINGS_INFO.THINGS_VENTIL:
 			state.put("power", splitStr[0]);
 			if(splitStr[0].equalsIgnoreCase("on")) {
-				if(splitStr[1].equals("mid")) state.put("fanSpeed", "middle");
+				if(splitStr.length == 1) state.put("fanSpeed", "low");
+				else if(splitStr[1].equals("mid")) state.put("fanSpeed", "middle");
 				else state.put("fanSpeed", splitStr[1]);
 			}
 			break;

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

@@ -28,7 +28,7 @@ public class RecieveiMapMultiSocket {
 		
 		logger.info("****************************************");
 		logger.info("Thread를 이용한 다중 접속 서버 작동됨...단지서버2.0 : " + bNewDanjiServer + " , 개발서버 : " + bDevVersion + " , 가스 1개 고정 : " + SERVERINFO.GasCount_HardCoding_One);
-		logger.info("연동 IP :" + SERVERINFO.SendEventURL + " , Port : " + SERVERINFO.SendEventPort);
+		logger.info("연동 IP :" + SERVERINFO.SendKakaoEventURL + " , Port : " + SERVERINFO.SendEventPort);
 		logger.info("월패드 수신 포트 :" + SERVERINFO.WalladReceivePort);
 		logger.info("****************************************");
 

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

@@ -2,6 +2,7 @@ package com.icontrols.kakao.socket.wallpad;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.Socket;
@@ -23,6 +24,7 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 
 import com.icontrols.kakao.common.KAKAO_RESULT;
+import com.icontrols.kakao.common.SERVERINFO;
 import com.icontrols.kakao.common.utils.BeanUtils;
 import com.icontrols.kakao.common.utils.XmlUtil;
 import com.icontrols.kakao.config.AsyncConfig;
@@ -66,68 +68,70 @@ public class ThreadServerHandler extends Thread {
 		InputStream InStm = null;
 		InputStreamReader ISR = null;
 		BufferedReader MsgReader = null;
+		StringBuffer sbRcvMSG = null;
+		boolean bRcvOK = false;
 		try {
 			// 클라이언트로 내용을 출력 할 객체 생성
 			InStm = connectedClientSocket.getInputStream();									// Socket으로 연결된 클라이언트에게 Input Stream 을 얻는다.
 			connectedClientSocket.setSoLinger(true, 3000);												// 소켓 옵션 설정 소켓이 닫힐 때 아직 전송되지 않은 데이터 처리에 대한 옵션 --> 3000초 의 linger time을 설정
 			
 			ISR = new InputStreamReader(InStm, "euc-kr");
-			MsgReader = new BufferedReader(new InputStreamReader(InStm, "euc-kr"));
+			MsgReader = new BufferedReader(ISR);
 			strRcvMSG = "";
 			
-			StringBuffer sbRcvMSG = new StringBuffer(); 												// Client에게 수신받은 iMap 메시지를 append한 뒤에 strRcvMSG에 할당한다.
+			sbRcvMSG = new StringBuffer(); 												// Client에게 수신받은 iMap 메시지를 append한 뒤에 strRcvMSG에 할당한다.
 			StringBuffer sbInBuffer = null;
 			
 //			String InBuffer;
 			
-			boolean bRcvOK = false;
 			lSocketConnectionPeriod = System.currentTimeMillis() + TIMEOUT_iMAP_WAIT; // 타임아웃시간을 설정한다.
 
 			while (System.currentTimeMillis() < lSocketConnectionPeriod) {
-				try {
-					if (MsgReader.ready()) {
-						try {
-							char[] ReadData = new char[SOCKET_BUFFER_SIZE_READ * 1024];
-							sbInBuffer = new StringBuffer();
-							while (MsgReader.ready()) {
-								long charCnt = MsgReader.read(ReadData);
-								sbInBuffer.append(new String(ReadData, 0, (int) charCnt));
-							}
-
-							if (sbInBuffer != null || sbInBuffer.toString().trim().length() > 0)
-								sbRcvMSG.append(sbInBuffer.toString());
-							
-							if (0 < sbInBuffer.toString().indexOf("</imap>")) { // </imap> 으로 제대로 닫혔다면 클라이언트의 이벤트 메세지를 제대로 수신 했다는 말.
-								bRcvOK = true;
-								logger.debug("[iMAPSvrProc().run()] Received DONE!!");
-								break;
-							}
-						} catch (Exception e) {
-							logger.error("message : " + e);
+				if (MsgReader.ready()) {
+					try {
+						char[] ReadData = new char[SOCKET_BUFFER_SIZE_READ * 1024];
+						sbInBuffer = new StringBuffer();
+						while (MsgReader.ready()) {
+							long charCnt = MsgReader.read(ReadData);
+							sbInBuffer.append(new String(ReadData, 0, (int) charCnt));
+						}
 
-							MsgReader.close();
-							ISR.close();
-							InStm.close();
-							return;
+						if (sbInBuffer != null || sbInBuffer.toString().trim().length() > 0)
+							sbRcvMSG.append(sbInBuffer.toString());
+						
+						if (0 < sbInBuffer.toString().indexOf("</imap>")) { // </imap> 으로 제대로 닫혔다면 클라이언트의 이벤트 메세지를 제대로 수신 했다는 말.
+							bRcvOK = true;
+							logger.debug("[iMAPSvrProc().run()] Received DONE!!");
+							break;
 						}
-					} else {
-						Thread.sleep(100);
+					} catch (Exception e) {
+						logger.error("message : " + e);
+
+						MsgReader.close();
+						ISR.close();
+						InStm.close();
+						return;
 					}
-				} catch (Exception e) {
-					logger.error("[Exception] iMAPSvrProc.run() ===== 2 =====");
-					connectedClientSocket.close();
-					logger.error("message : " + e);
-					e.printStackTrace();
-					return;
-				}finally {
-					strRcvMSG = sbRcvMSG.toString();
-					
-					MsgReader.close();
-					ISR.close();
-					InStm.close();
+				} else {
+					Thread.sleep(100);
 				}
 			}
+		} catch (Exception e) {
+			logger.error("[Exception] iMAPSvrProc.run() ===== 2 =====");
+			logger.error("message : " + e);
+			e.printStackTrace();
+
+			try { connectedClientSocket.close(); } catch (IOException e1) { e1.printStackTrace(); }
+			return;
+		}finally {
+			strRcvMSG = sbRcvMSG.toString();
 
+			try { MsgReader.close(); } catch (IOException e) { e.printStackTrace(); }
+			try { ISR.close(); } catch (IOException e) { e.printStackTrace(); }
+			try { InStm.close(); } catch (IOException e) { e.printStackTrace(); }
+		}
+		
+		try {
 			if (!bRcvOK) {
 				logger.error("[iMAPSvrProc().run()] iMAP message is unacceptable!! :\n\r" + strRcvMSG);
 				connectedClientSocket.close();
@@ -169,12 +173,9 @@ public class ThreadServerHandler extends Thread {
 //				}
 			}
 		} catch (Exception e) {
-			try {
-				connectedClientSocket.close();
-			} catch (Exception E) {
-				logger.error("message : " + E);
-			}
 			logger.error("message : " + e);
+		}finally {
+			try { if(!connectedClientSocket.isClosed()) connectedClientSocket.close(); } catch (Exception E) { logger.error("message : " + E); }			
 		}
 	}
 
@@ -184,7 +185,6 @@ public class ThreadServerHandler extends Thread {
 		private Document doc;
 		private String cmd;
 		
-		
 		// 생성자
 		public DeviceEventMsgHandler(Document doc, String cmd) {
 			this.doc = doc;
@@ -236,6 +236,8 @@ public class ThreadServerHandler extends Thread {
 				
 				Map <String, Object> body = new HashMap<String, Object>();
 				
+//				String elkLogMessage = "[Device Status Event] ip: " + SERVERINFO.danziServerExIp + " dong: " + dong + " ho: " + ho +" model_id: " + model_id + " dev_num: " + dev_num + " status:  "+ status;
+//				logger.info(elkLogMessage);
 				
 				AsyncConfig asyncConfig = (AsyncConfig)BeanUtils.getBean("asyncConfig");
 				

+ 4 - 3
src/main/java/com/icontrols/kakao/socket/wallpad/UnlinkExtensionHandler.java

@@ -36,6 +36,7 @@ public class UnlinkExtensionHandler extends Thread{
 	}
 	
 	public void run() {
+		Map<String, Object> retMap = null;
 		try {
 			logger.info("[UnlinkExtensionHandler] - [START]");
 			DonghoInfoRepository dRepo = (DonghoInfoRepository)BeanUtils.getBean("donghoInfoRepository");
@@ -59,14 +60,14 @@ public class UnlinkExtensionHandler extends Thread{
 			
 			// 해당 동호수에 인원이 없을 경우 월패드 구독 해지를 진행해야 한다.
 			authService = (AuthService)BeanUtils.getBean("authServiceImpl");
-			Map<String, Object> retMap = authService.subscriptionProcess(subsMap);
+			retMap = authService.subscriptionProcess(subsMap);
 			
-			logger.info("[해지결과] - [" + dong + "]-[" + ho +"]" + retMap.toString());
+			
+			logger.info("[UnlinkExtensionHandler] - [END] - [dong:"+this.dong+"]-[ho:"+this.ho+"]-[RESULT:" + retMap.toString()+"]");
 		}catch(Exception e) {
 			logger.error("[UnlinkExtensionHandler] - [ERROR] - " + e.getMessage());
 			e.printStackTrace();
 		}finally {
-			logger.info("[UnlinkExtensionHandler] - [END]");
 		}
 	}
 }

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

@@ -80,8 +80,7 @@ public class WallpadMsgSender {
 			.append(XMLGenerator.MakeXMLTail());
 		
 			xmlData = sb.toString();
-			logger.info("[SUBS]");
-			logger.info(sb.toString());
+			logger.info("[SUBS] - " + sb.toString());
 			int bRet = imapSocket.doWork(xmlData);
 			
 			if(bRet < 0) {

+ 54 - 0
src/main/resources/application_setting_info.dat

@@ -0,0 +1,54 @@
+## 여기에 설정값을 입력한다.
+## 카카오 제휴서비스에 필요한 정보이며
+## 단지별로 적요을 위해 Maven build를 하지 않으려는 목적으로
+## 배포파일의 버전이 빌드되면 계속 그 빌드 버전으로 배포할 것.
+## 아래 설정값만 단지에 맞게 장성한다.
+## {KEY}:{VALUE} 로 작성하면 되고
+## 설정을 추가하려면 ',' 를 추가한뒤 설정 정보를 추가하면 된다.
+## 프로젝트 root 폴더에 옮겨놓으면 된다. (/service/kakao/)
+
+# 아파트의 단지코드를 입력한다.
+aptCode=DEVVALLEY_12345678, 
+
+# 단지 설치정보
+danziInfo=연구소단지서버,
+
+# SANDBOX-BETA-RELEASE 순이며 개발할때는 샌드박스버전으로 개발하면 된다.
+settingVersion=SANDBOX,
+
+# 배포버전.
+# 되도록이면 배포버전이 업데이트되면 여기도 수정좀 하자~
+releaseVersion=1.0.0,
+
+# 단지서버의 접속 아이피를 작성한다.
+danziServerExip=61.33.215.54,
+
+# 월패드에 제어요청 보내기 위한 포트정보
+wallpadSocketPort=10002,
+
+# 세대별 제어 이벤트를 받기위한 소켓서버 설정포트
+eventSocketPort=2222,
+
+# 단지서버 기본정보.
+danziServerIP=10.0.1.1,
+
+# 이벤트를 전달하기위한 중계서버 URL/Port 정보
+sendKakaoEventURL=https://proxy.hdc-smart.com:80,
+
+# 카카오 리퀘스트의 유효성검증을 위한 ClientId/ClientSecret 정보
+kakaoHeaderClientId=PANGWMGNAP,
+kakaoHeaderClientSecret=QWSAZXCDERFVBGTYHNMJ,
+
+# 카카오에 이벤트 보낼때 필요한  ClientId/Secret 정보
+kakaoEventClientId=MULdruZb2xgbDj2jzEk32TSPEBP9dsFN,
+kakaoEventClientSecret=RSUBDYEfs36iuGBRm3tR9pDJmTjMphgo,
+
+# 카카오i 월패드 적용현장
+kakaoIWallpadAccess=true
+
+
+
+ 
+
+
+

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

@@ -12,7 +12,7 @@
             <maxHistory>60</maxHistory>
         </rollingPolicy>
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
-            <level>DEBUG</level>
+            <level>INFO</level>
         </filter>
 
         <encoder>
@@ -20,7 +20,7 @@
         </encoder>
     </appender>
     
-    <logger name="com.icontrols.kakao" level="info"></logger>
+    <logger name="com.icontrols.kakao" level="INFO"></logger>
 
     <root level="INFO">
         <appender-ref ref="dailyRollingFileAppender" />