Quellcode durchsuchen

[WallPadAPI]
1. 거동수상자 감지시간 및 횟수 설정 추가
2. 안면인식 관련 설정 추가 (나중을 위해 추가)
3. 안면인식 DB 추가(나중을 위해 추가)
4. 자동 일괄 소등 설정 추가(필요없음)
5. 안면인식 관련 클래스 추가(WallPadFaceIDRegData)(나중을 위해 추가)
6. 최신 jar 추가

jglee vor 2 Wochen
Ursprung
Commit
31cd018cd4

BIN
WallPadAPI/jar/WallPadAPI.jar


BIN
WallPadAPI/jar/WallPadAPIforSVC.jar


+ 238 - 4
WallPadAPI/src/main/java/com/artncore/WallPadDataMgr/WallpadAccessData.java

@@ -28,6 +28,8 @@ public class WallpadAccessData extends wallpaddbmgr
         public final static String WPAD_CTRL      = "WPAD_CTRL";
         /** 스마트키에 의한 문열림 */
         public final static String SMART_KEY      = "SMART_KEY";
+        /** 안면인식에 의한 문열림 */
+        public final static String FACE_ID        = "FACE_ID";
         /** 무선리모콘에 의한 문열림 */
         public final static String REMOCON        = "REMOCON";
         /** 주방TV에 의한 문열림 */
@@ -38,6 +40,8 @@ public class WallpadAccessData extends wallpaddbmgr
         public final static String SUB_DEVICE     = "SUB_DEVICE";
         /** 스마트키감지됨 (디버깅전용) */
         public final static String SMART_KEY_DETECTION = "SMART_KEY_DETECTION";
+        /** 안면인식 감지됨 (디버깅전용) */
+        public final static String FACE_ID_DETECTION = "FACE_ID_DETECTION";
         /** 도어락 비밀번호/카드 인식 5회 초과 */
         public final static String FPDLOCK_PWDCARD_5OVER = "FPDLOCK_PWDCARD_5OVER";
         /** 도어락 지문인식 10회 초과 */
@@ -48,7 +52,24 @@ public class WallpadAccessData extends wallpaddbmgr
         public final static String CARDKEY        = "CARDKEY";
         /** 지문 출입 */
         public final static String FINGER_PRINT   = "FINGER_PRINT";
-
+        /** 내부 문열림 출입 */
+        public final static String IN_OPEN   = "IN_OPEN"; //jglee - 2023.03.20 양방향 도어락 문열림 모드 추가
+        /** 문열림 대기 출입 */
+        public final static String DOORWAIT   = "DOORWAIT"; //jglee - 2023.03.20 양방향 도어락 문열림 모드 추가
+        /** 로비폰 출입 */
+        public final static String mpasswd = "mpasswd"; // 마스터 패스워드 입력
+        public final static String passwd = "passwd"; // 세대 패스워드 입력
+        public final static String adminpw = "adminpw"; // 관리자 출입 비밀번호
+        public final static String mcard = "mcard"; // 마스터 카드사용
+        public final static String dcard = "dcard"; // 동 마스터 카드
+        public final static String card = "card"; // 세대 카드
+        public final static String onepass = "onepass"; // 원패스
+        public final static String mcard_extra = "mcard_extra"; // 타단지 마스터 카드
+        public final static String dcard_extra = "dcard_extra"; // 타단지 동 마스터 카드
+        public final static String card_extra = "card_extra"; // 타단지 세대 카드
+        public final static String call = "call"; // 통화후 문열림 기능에 의한 출입 시도
+        public final static String callguard = "callguard"; // 경비에 의한 문열림
+        public final static String face_key = "face_key"; // 얼굴인식 로비폰 출입 시도
 
         /**
          * 범위체크
@@ -62,16 +83,34 @@ public class WallpadAccessData extends wallpaddbmgr
             if(CheckStr.equals(WPAD_CALL)) return true;
             if(CheckStr.equals(WPAD_CTRL)) return true;
             if(CheckStr.equals(SMART_KEY)) return true;
+            if(CheckStr.equals(FACE_ID)) return true;
             if(CheckStr.equals(REMOCON)) return true;
             if(CheckStr.equals(KITCHEN_TV)) return true;
             if(CheckStr.equals(BATHROOM_PHONE)) return true;
             if(CheckStr.equals(SUB_DEVICE)) return true;
             if(CheckStr.equals(SMART_KEY_DETECTION)) return true;
+            if(CheckStr.equals(FACE_ID_DETECTION)) return true;
             if(CheckStr.equals(FPDLOCK_PWDCARD_5OVER)) return true;
             if(CheckStr.equals(FPDLOCK_FP_10OVER)) return true;
             if(CheckStr.equals(PASSWORD)) return true;
             if(CheckStr.equals(CARDKEY)) return true;
             if(CheckStr.equals(FINGER_PRINT)) return true;
+            if(CheckStr.equals(IN_OPEN)) return true;
+            if(CheckStr.equals(DOORWAIT)) return true;
+            // 로비폰
+            if(CheckStr.equals(mpasswd)) return true;
+            else if (CheckStr.equals(passwd)) return true;
+            else if(CheckStr.equals(adminpw)) return true;
+            else if(CheckStr.equals(mcard)) return true;
+            else if(CheckStr.equals(dcard)) return true;
+            else if(CheckStr.equals(card)) return true;
+            else if(CheckStr.equals(onepass)) return true;
+            else if(CheckStr.equals(mcard_extra)) return true;
+            else if(CheckStr.equals(dcard_extra)) return true;
+            else if(CheckStr.equals(card_extra)) return true;
+            else if(CheckStr.equals(call)) return true;
+            else if(CheckStr.equals(callguard)) return true;
+            else if(CheckStr.equals(face_key)) return true;
             return false;
         }
 
@@ -87,16 +126,35 @@ public class WallpadAccessData extends wallpaddbmgr
             if(CheckStr.equals(WPAD_CALL)) return "월패드 [통화]";
             if(CheckStr.equals(WPAD_CTRL)) return "월패드 [제어]";
             if(CheckStr.equals(SMART_KEY)) return "스마트키";
+            if(CheckStr.equals(FACE_ID)) return "얼굴인식";
             if(CheckStr.equals(REMOCON)) return "무선리모콘";
             if(CheckStr.equals(KITCHEN_TV)) return "주방TV";
             if(CheckStr.equals(BATHROOM_PHONE)) return "욕실폰";
             if(CheckStr.equals(SUB_DEVICE)) return "서브기기";
             if(CheckStr.equals(SMART_KEY_DETECTION)) return "스마트키감지";
+            if(CheckStr.equals(FACE_ID_DETECTION)) return "얼굴인식감지";
+            //if(CheckStr.equals(FACE_ID_DETECTION)) return "얼굴인식";
             if(CheckStr.equals(FPDLOCK_PWDCARD_5OVER)) return "비밀번호/카드 5회초과";
             if(CheckStr.equals(FPDLOCK_FP_10OVER)) return "지문인식 10회초과";
             if(CheckStr.equals(PASSWORD)) return "비밀번호 출입";
             if(CheckStr.equals(CARDKEY)) return "카드키 출입";
             if(CheckStr.equals(FINGER_PRINT)) return "지문인식 출입";
+            if(CheckStr.equals(IN_OPEN)) return "내부 문열림 출입";
+            if(CheckStr.equals(DOORWAIT)) return "문열림 대기모드 출입";
+            // 로비폰
+            if(CheckStr.equals(mpasswd)) return "로비폰 [마스터 비밀번호]";
+            else if(CheckStr.equals(passwd)) return "로비폰 [세대 비밀번호]";
+            else if(CheckStr.equals(adminpw)) return "로비폰 [관리자 출입 비밀번호]";
+            else if(CheckStr.equals(mcard)) return "로비폰 [마스터 카드]";
+            else if(CheckStr.equals(dcard)) return "로비폰 [동 마스터 카드]";
+            else if(CheckStr.equals(card)) return "로비폰 [세대 카드]";
+            else if(CheckStr.equals(onepass)) return "로비폰 [원패스]";
+            else if(CheckStr.equals(mcard_extra)) return "로비폰 [타단지 마스터 카드]";
+            else if(CheckStr.equals(dcard_extra)) return "로비폰 [타단지 동 마스터 카드]";
+            else if(CheckStr.equals(card_extra)) return "로비폰 [타단지 세대 카드]";
+            else if(CheckStr.equals(call)) return "로비폰 [통화 후 문열림]";
+            else if(CheckStr.equals(callguard)) return "로비폰 [경비실]";
+            else if(CheckStr.equals(face_key)) return "로비폰 [안면 인식]";
             return "정의되지않음";
         }
     }
@@ -115,6 +173,8 @@ public class WallpadAccessData extends wallpaddbmgr
         public Calendar Date;
         /** 시리얼 넘버 */
         public String   SerialNumber;
+        /** 안면인식ID 별명 */
+        public String   Nickname;
 
         /** 생성자 */
         public AccessDataClass()
@@ -123,6 +183,7 @@ public class WallpadAccessData extends wallpaddbmgr
             Kind = null;
             Date = null;
             SerialNumber = null;
+            Nickname = null;
         }
         /** 디버깅 String 출력 */
         public String ToDebugString(int index)
@@ -136,6 +197,7 @@ public class WallpadAccessData extends wallpaddbmgr
                             "Date         : " + Date.get(Calendar.YEAR) + "-" + (int)(Date.get(Calendar.MONTH)+1) + "-" + Date.get(Calendar.DAY_OF_MONTH) + "  " +
                             Date.get(Calendar.HOUR_OF_DAY) + ":" + Date.get(Calendar.MINUTE) + ":" + Date.get(Calendar.SECOND) + "\r\n" +
                             "SerialNumber : " + SerialNumber + "\r\n" +
+                            "Nickname     : " + Nickname + "\r\n" +
                             "==========================\r\n\r\n";
             return retStr;
         }
@@ -149,6 +211,7 @@ public class WallpadAccessData extends wallpaddbmgr
     public WallpadAccessData(Context ctx)
     {
         super(ctx);
+
         if (!CheckTableExist(AccessTBL))
         {
             try
@@ -165,6 +228,69 @@ public class WallpadAccessData extends wallpaddbmgr
                 LogUtil.errorLogInfo("", TAG, e);
             }
         }
+//        else {
+//            Log.v("yjyoon", "current CreateAccessDB: " + CreateAccessDB);
+//
+//            Cursor cursor = wdb.rawQuery("SELECT sql FROM sqlite_master WHERE tbl_name='AccessDB';", null);
+//            cursor.moveToPosition(0);
+//            Log.v("yjyoon", "now CreateAccessDB: " + cursor.getString(0));
+//            cursor.close();
+//
+//        }
+    }
+
+    /**
+     * 출입정보 DB에 nickname column 존재 여부를 확인하여, 없으면 해당 column을 추가한다.
+     * (안면인식 현관폰 연동시 필요하여 필드 추가)
+     * @return (boolean) - > true : 성공, false : 실패
+     */
+    public boolean checkNickNameColumn() {
+        try {
+            if (wdb != null) {
+                Cursor cursor1 = wdb.rawQuery("SELECT sql FROM sqlite_master WHERE name='" + AccessTBL + "' AND sql LIKE '%Nickname%'", null);
+                int ret1 = cursor1.getCount();
+                cursor1.close();
+                Log.i(TAG, "[checkNickNameColumn] ret1 [" + ret1 + "]");
+                if (0 < ret1) {
+                    Log.i(TAG, "[checkNickNameColumn] Exist Nickname column!!");
+                    return true;
+                }
+                else {
+                    Log.w(TAG, "[checkNickNameColumn] Not exist Nickname column!! Add Nickname column!!");
+                    wdb.execSQL("ALTER TABLE " + AccessTBL + " ADD COLUMN Nickname");
+                    Log.i(TAG, "[checkNickNameColumn] Added Nickname column!!");
+                    return true;
+                }
+            }
+            else {
+                Log.w(TAG, "[checkNickNameColumn] wdb is null!!");
+                return false;
+            }
+        } catch (RuntimeException re) {
+            Log.e(TAG, "[RuntimeException] checkNickNameColumn()");
+            LogUtil.errorLogInfo("", TAG, re);
+            return false;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] checkNickNameColumn()");
+            LogUtil.errorLogInfo("", TAG, e);
+            return false;
+        }
+    }
+
+    public Cursor doRawQuery(String query) {
+        try {
+            Log.i(TAG, "[doRawQuery] query [" + query + "]");
+            Cursor cursor = wdb.rawQuery(query, null);
+            return cursor;
+        } catch (RuntimeException re) {
+            Log.e(TAG, "[RuntimeException] doRawQuery(String query)");
+            LogUtil.errorLogInfo("", TAG, re);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "[Exception] doRawQuery(String query)");
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
     }
 
     /**
@@ -196,13 +322,22 @@ public class WallpadAccessData extends wallpaddbmgr
                 return -3;
             }
         }
+        if(Kind.equals(KIND.FACE_ID))
+        {
+            // sn: FaceID 또는 닉네임
+            if(sn == null)
+            {
+                Log.w(TAG, "[Insert] Param - faceId is null !!!");
+                return -4;
+            }
+        }
 
         // 2. Count Check & Delete
         int Count = getCount();
         if(Count < 0)
         {
             Log.w(TAG, "[Insert] getCount() Error !!! (Count:" + Count + ")");
-            return -4;
+            return -5;
         }
         if(Count >= MAX_COUNT)
         {
@@ -246,6 +381,96 @@ public class WallpadAccessData extends wallpaddbmgr
         return 0;
     }
 
+    /**
+     * 출입 데이터를 추가한다.
+     *
+     * @param Kind - (String) {@link KIND} 에 따른다.
+     * @param sn   - (String) Kind 가 SMART_KEY 일 경우에만, 사용한다. (키 고유번호를 입력한다)
+     *
+     * @return (int) - >0 : 성공, <=0 : 실패
+     */
+    public int Insert(String Kind, String sn, String Nickname)
+    {
+        // 1. Param Range Check
+        if(Kind == null)
+        {
+            Log.w(TAG, "[Insert] Param - Kind is null !!!");
+            return -1;
+        }
+        if(!KIND.RangeCheck(Kind))
+        {
+            Log.w(TAG, "[Insert] Param - Kind RangeCheck Error (" + Kind + ")");
+            return -2;
+        }
+        if(Kind.equals(KIND.SMART_KEY))
+        {
+            if(sn == null)
+            {
+                Log.w(TAG, "[Insert] Param - sn is null !!!");
+                return -3;
+            }
+        }
+        if(Kind.equals(KIND.FACE_ID))
+        {
+            // sn: FaceID 또는 닉네임
+            if(sn == null)
+            {
+                Log.w(TAG, "[Insert] Param - faceId is null !!!");
+                return -4;
+            }
+        }
+
+        // 2. Count Check & Delete
+        int Count = getCount();
+        if(Count < 0)
+        {
+            Log.w(TAG, "[Insert] getCount() Error !!! (Count:" + Count + ")");
+            return -5;
+        }
+        if(Count >= MAX_COUNT)
+        {
+            int DelCount = Count - (int)(MAX_COUNT-1);
+
+            for(int i=0 ; i<DelCount ; i++)
+            {
+                int ret = Delete(0);
+                if(ret < 0)
+                {
+                    Log.w(TAG, "[Insert] Delete() Error !!! (ret:" + ret + ")");
+                }
+            }
+        }
+
+        // 2. Put
+        ContentValues values = new ContentValues();
+
+        //     2.1. Kind
+        values.put("Kind"   , Kind);
+
+        //     2.2. Date
+        Calendar cal = new GregorianCalendar();
+        String DateStr = cal.get(Calendar.YEAR)           + ":" +
+                (int)(cal.get(Calendar.MONTH)+1) + ":"+
+                cal.get(Calendar.DAY_OF_MONTH)   + ":" +
+                cal.get(Calendar.HOUR_OF_DAY)    + ":" +
+                cal.get(Calendar.MINUTE)         + ":" +
+                cal.get(Calendar.SECOND);
+        values.put("Date"     , DateStr);
+
+        //     2.3. SerialNumber
+        if(sn != null) values.put("SerialNumber" , sn);
+
+        //     2.4. Nickname
+        if(Nickname != null) values.put("Nickname" , Nickname);
+
+        // 3. insert
+        if(wdb!=null) {
+            long ret = wdb.insert(AccessTBL, null, values);
+            if (ret < 0) return -10;
+        }
+        return 0;
+    }
+
     /**
      * 출입 데이터를 개별 삭제 한다.
      *
@@ -400,7 +625,7 @@ public class WallpadAccessData extends wallpaddbmgr
     }
 
     /**
-     * 등록되어있는 SmartKey 데이터 List 를 반환한다.
+     * 등록되어있는 SmartKey, FaceID 데이터 List 를 반환한다.
      *
      * @return (List<SmartKeyDataClass>) 등록 데이터 List
      */
@@ -408,11 +633,13 @@ public class WallpadAccessData extends wallpaddbmgr
     {
         if(wdb!=null)
         {
-            Cursor cursor = wdb.rawQuery("select seqnum, Kind, Date, SerialNumber from " + AccessTBL + ";", null);
+            Cursor cursor = wdb.rawQuery("select seqnum, Kind, Date, SerialNumber, Nickname from " + AccessTBL + ";", null);
             try
             {
                 SyncData.clear();
                 String DateStr = null;
+                String Nickname = null;
+
                 while (cursor.moveToNext())
                 {
                     AccessDataClass getdata = new AccessDataClass();
@@ -421,6 +648,13 @@ public class WallpadAccessData extends wallpaddbmgr
                     getdata.Kind         = cursor.getString(1);
                     DateStr              = cursor.getString(2);
                     getdata.SerialNumber = cursor.getString(3);
+                    Nickname             = cursor.getString(4);
+
+                    if (Nickname != null && !Nickname.isEmpty()) {
+                        getdata.Nickname = Nickname;
+                    } else {
+                        getdata.Nickname = getdata.SerialNumber;
+                    }
 
                     String[] retData = null;
                     retData = DateStr.split(":");

+ 266 - 0
WallPadAPI/src/main/java/com/artncore/WallPadDataMgr/WallpadDeviceSet.java

@@ -118,6 +118,79 @@ public class WallpadDeviceSet extends wallpaddbmgr {
 
 	public int mModelType = Version.getModelType();
 
+	/**
+	 * 현관카메라 종류 가져오는 함수
+	 *
+	 * param none
+	 * @return [(int) 현관카메라 사용여부 (1:사용함 , 0:사용하지 않음),<br>  (int)카메라 종류 (0:기본 , 1:RF현관카메라, 2:스마트키, 3:UKS, 4:ETC)]
+	 */
+	public int[] getFrontCameraSettingInfo() {
+		String[] GetData = GetSettingData("현관카메라");
+
+		int returnData[] = { 1, DOORTYPE_BASIC };
+		try {
+			if (GetData == null) {
+				Log.w(TAG, "[getFrontCameraSettingInfo] GetData is null!!");
+				return returnData;
+			}
+
+//			Log.e(TAG, "[getFrontCameraSettingInfo] GetData: " + Arrays.toString(GetData));
+
+			String strValue = GetData[0];
+			if (!strValue.equalsIgnoreCase("현관카메라")) {
+				Log.w(TAG, "[getFrontCameraSettingInfo] The name is wrong!! must be 현관카메라, strValue -> " + strValue);
+				return returnData;
+			}
+
+			strValue = GetData[1];
+			strValue = strValue.replace('(', '_');
+			strValue = strValue.replace(':', '_');
+			strValue = strValue.replace(')', '_');
+
+			String[] astrDetailValue = strValue.split("_");
+
+//			Log.e(TAG, "[getFrontCameraSettingInfo] astrDetailValue: " + Arrays.toString(astrDetailValue));
+
+			if (astrDetailValue[3].equalsIgnoreCase("사용함")) returnData[0] = DO_USE;
+			else {
+				returnData[0] = DO_NOT_USE;
+				return returnData;
+			}
+
+			if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_DEFAULT)) returnData[1] = DOORTYPE_BASIC;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_RF_DOOR_CAMERA)) returnData[1] = DOORTYPE_RFCAM;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_SMART_KEY_EXTERNAL)) returnData[1] = DOORTYPE_SMARTKEY_EXTERNAL;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_SMART_KEY)) returnData[1] = DOORTYPE_SMARTKEY;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_UKS)) returnData[1] = DOORTYPE_UKS;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_ETC)) returnData[1] = DOORTYPE_ETC;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_IOT_SMART)) returnData[1] = DOORTYPE_IOT_SMART;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_HYOSUNG_SMART)) returnData[1] = DOORTYPE_HYOSUNG_SMART;
+			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_DAEWOO_SMART)) returnData[1] = DOORTYPE_DAEWOO_SMART;
+//			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_HD_DOOR_CAMERA)) returnData[1] = DOORTYPE_HDCAM;
+//			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_SMARTKEY_BLACKBOX_NORMALCAM)) returnData[1] = DOORTYPE_SMARTKEY_BLACKBOX_NORMALCAM;
+//			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_SMARTKEY_BLACKBOX_FACIALCAM)) returnData[1] = DOORTYPE_SMARTKEY_BLACKBOX_FACIALCAM;
+//			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_EXTERNAL_HD_DOOR_CAMERA)) returnData[1] = DOORTYPE_EXTERNAL_HD_DOOR_CAMERA; // jglee - 2023.02.21 HD현관카메라
+//			else if (astrDetailValue[5].equalsIgnoreCase(DOOR_CAMERA_TYPE_EXTERNAL_HD_SMART_DOOR_CAMERA)) returnData[1] = DOORTYPE_EXTERNAL_HD_SMART_DOOR_CAMERA; // jglee - 2025.02.24 HD현관카메라
+			else {
+				returnData[0] = DO_USE;
+				returnData[1] = DOORTYPE_BASIC;
+			}
+			return returnData;
+		} catch (RuntimeException re) {
+			Log.e(TAG, "[RuntimeException] getFrontCameraSettingInfo()");
+			LogUtil.errorLogInfo("", TAG, re);
+			returnData[0] = 1;
+			returnData[1] = DOORTYPE_BASIC;
+			return  returnData;
+		} catch (Exception e) {
+			Log.e(TAG, "[Exception] getFrontCameraSettingInfo()");
+			LogUtil.errorLogInfo("", TAG, e);
+			returnData[0] = 1;
+			returnData[1] = DOORTYPE_BASIC;
+			return  returnData;
+		}
+	}
+
 	public int[] Get_Light_info() {
 		String[] GetData = GetSettingData("조명제어기");
 		int[] returnData = {1,LIGHT_TYPE_LIVING, 6};
@@ -4842,6 +4915,161 @@ public class WallpadDeviceSet extends wallpaddbmgr {
 		}
 	}
 
+
+	/**
+	 * 변경된 시나리오에 따라 거동수상자 감지 대기 시간 시간 가져오는 용도로 사용
+	 * @return 10 / 20 / 30 / 40 / 50 / 60(기본값) / 180 / 360 / 600 초
+	 */
+	public int Get_SmartDoorCam_Dutaion() {
+		String[] GetData = GetSettingData(define.DEVICE_ID_SMARTCAM_DURATION);
+
+		int returnData = 60; // 기본값: 60초
+		try {
+			if (GetData == null) return returnData;
+
+			if (GetData[1].indexOf("사용함") > 0) {
+
+				String devInfo = GetData[1];
+				devInfo = devInfo.replace('(', '_');
+				devInfo = devInfo.replace(':', '_');
+				devInfo = devInfo.replace(')', '_');
+
+				String[] parseData = devInfo.split("_");
+
+				//[0] - 기기번호
+				//[1] - 회로수
+				//[2] - 기기이름
+				//[3] - 사용유무 (사용함 or 사용안함)------------> 사용할 정보
+				//[4] - 시간정보 (종류)
+
+				if(parseData.length != 6)
+				{
+					Log.d(TAG, "[Get_SmartDoorCam_Duration]Parsing Error : InputData [" + GetData[1] +"]" );
+					return returnData;
+				}
+
+				//값에 초가 있는 경우
+				if(parseData[5].contains("초"))
+				{
+					parseData[5] = parseData[5].replace("초", "");
+				}
+				//값에 초가 없으면 기본적으로 데이터를 초 기준으로 판단
+				returnData = Integer.parseInt(parseData[5]);
+			}
+			Log.d(TAG, "[Get_SmartDoorCam_Duration] returnData [" + returnData + "]");
+
+			return returnData;
+		} catch (RuntimeException re) {
+			Log.e(TAG, "[RuntimeException] Get_SmartDoorCam_Duration()");
+			LogUtil.errorLogInfo("", TAG, re);
+			return  returnData;
+		} catch (Exception e) {
+			Log.e(TAG, "[Exception] Get_SmartDoorCam_Duration()");
+			LogUtil.errorLogInfo("", TAG, e);
+			return  returnData;
+		}
+	}
+
+
+	/**
+	 * 거동수상자 감지 대기 시간
+	 * @param isUse 사용 여부
+	 * @param duration 대기시간
+	 */
+	public void Set_SmartDoorCam_Duration(boolean isUse, int duration) {
+		try
+		{
+			String _use = isUse ? "사용함" : "사용안함";
+			String value = String.valueOf(duration) + "초";
+			String inputValue;
+			if(isUse)
+				inputValue = "1(1:" + define.DEVICE_ID_SMARTCAM_DURATION + "(" + _use + ")종류(" + value + ")";
+			else
+				inputValue = "1(1:" + define.DEVICE_ID_SMARTCAM_DURATION + "(" + _use + ")";
+
+			UpdateSettingData("subdev_list", define.DEVICE_ID_SMARTCAM_DURATION, 0, inputValue);
+		}
+		catch (Exception e)
+		{
+			Log.e(TAG, "[Exception] Set_SmartDoorCam_Duration( isUse : " + isUse + ", Duration : " + duration + ")");
+		}
+	}
+
+	/**
+	 * 거동수상자 감지 횟수
+	 * @param isUse 사용 여부
+	 * @param count 횟수
+	 */
+	public void Set_SmartDoorCam_CheckCount(boolean isUse, int count) {
+		try
+		{
+			String _use = isUse ? "사용함" : "사용안함";
+			String value = String.valueOf(count);
+			String inputValue;
+			if(isUse)
+				inputValue = "1(1:" + define.DEVICE_ID_SMARTCAM_COUNT + "(" + _use + ")종류(" + value + ")";
+			else
+				inputValue = "1(1:" + define.DEVICE_ID_SMARTCAM_COUNT + "(" + _use + ")";
+
+			UpdateSettingData("subdev_list", define.DEVICE_ID_SMARTCAM_COUNT, 0, inputValue);
+		}
+		catch (Exception e)
+		{
+			Log.e(TAG, "[Exception] Set_SmartDoorCam_CheckCount( isUse : " + isUse + ", Count : " + count + ")");
+		}
+	}
+
+	/**
+	 * 변경된 시나리오에 따라 거동수상자 감지 기준 횟수를 가져온다.
+	 * @return 1 / 5(기본값) / 10
+	 */
+	public int Get_SmartDoorCam_Check_Count() {
+		String[] GetData = GetSettingData(define.DEVICE_ID_SMARTCAM_COUNT);
+
+		int returnData = 5; // 기본값: 5
+		try {
+			if (GetData == null) return returnData;
+
+			if (GetData[1].indexOf("사용함") > 0) {
+
+				String devInfo = GetData[1];
+				devInfo = devInfo.replace('(', '_');
+				devInfo = devInfo.replace(':', '_');
+				devInfo = devInfo.replace(')', '_');
+
+				String[] parseData = devInfo.split("_");
+
+				//[0] - 기기번호
+				//[1] - 회로수
+				//[2] - 기기이름
+				//[3] - 사용유무 (사용함 or 사용안함)------------> 사용할 정보
+				//[4] - 카운트정보 (종류)
+
+				if(parseData.length != 6)
+				{
+					Log.d(TAG, "[Get_SmartDoorCam_Check_Count]Parsing Error : InputData [" + GetData[1] +"]" );
+					return returnData;
+				}
+
+				//String -> Int
+				returnData = Integer.parseInt(parseData[5]);
+			}
+			Log.d(TAG, "[Get_SmartDoorCam_Check_Count] returnData [" + returnData + "]");
+
+			return returnData;
+		} catch (RuntimeException re) {
+			Log.e(TAG, "[RuntimeException] Get_SmartDoorCam_Check_Count()");
+			LogUtil.errorLogInfo("", TAG, re);
+			return  returnData;
+		} catch (Exception e) {
+			Log.e(TAG, "[Exception] Get_SmartDoorCam_Check_Count()");
+			LogUtil.errorLogInfo("", TAG, e);
+			return  returnData;
+		}
+	}
+
+
+
 	/**
 	 * 제어기능 사용 유무
 	 **/
@@ -5185,4 +5413,42 @@ public class WallpadDeviceSet extends wallpaddbmgr {
 		return returnData;
 	}
 
+
+	/**
+	 * jglee - 2024.10.16
+	 * 자동일괄소등 해제 기능 사용 여부(기본값 사용함)
+	 * 현산향, 에너지미터, 거실릴레이보드 같이 사용 시 이슈 동기화가 안맞음
+	 * @return
+	 */
+	public int Get_Auto_AllightOff()
+	{
+		String[] GetData = GetSettingData("자동일괄소등해제");
+
+		int returnData = 1;
+		try
+		{
+			if (GetData == null) return returnData;
+
+			if (GetData[1].indexOf("사용함") > 0) returnData = 1;
+			else
+			{
+				returnData = 0;
+				return returnData;
+			}
+
+			return returnData;
+		}
+		catch (RuntimeException re) {
+			LogUtil.errorLogInfo("", TAG, re);
+			returnData = 1;
+			return  returnData;
+		}
+		catch (Exception e) {
+			//e.printStackTrace();
+			LogUtil.errorLogInfo("", TAG, e);
+			returnData = 1;
+			return  returnData;
+		}
+	}
+
 }

+ 857 - 0
WallPadAPI/src/main/java/com/artncore/WallPadDataMgr/WallpadFaceIDRegData.java

@@ -0,0 +1,857 @@
+package com.artncore.WallPadDataMgr;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.util.Log;
+
+import com.util.LogUtil;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+public class WallpadFaceIDRegData extends wallpaddbmgr
+{
+    private final static String TAG = "WallpadFaceIDRegData";
+
+    public List<FaceIDDataClass> SyncData = new ArrayList<FaceIDDataClass>();
+
+    private final String INIT_HEX = "00000000";
+    private final String INIT_DATE = "0000:00:00:00:00:00";
+
+    private final int USED_FALSE = 0;
+    private final int USED_TRUE  = 1;
+
+    private final int MAX_COUNT = 255;
+
+    /**
+     * 안면인식ID 데이터 포멧 클래스
+     */
+    public static class FaceIDDataClass
+    {
+        /** 키 일련번호 - 범위 (1~10) */
+        public int      id;
+
+        /** 안면인식ID 정보 */
+        public String   FaceID;
+
+        /** 등록 일자 */
+        public Calendar RegDateCal;
+        /** 최종사용 일자 */
+        public Calendar LastUseDateCal;
+        /** 닉네임 */
+        public String   Nickname;
+
+        public FaceIDDataClass()
+        {
+            id = -1;
+            FaceID = null;
+            RegDateCal = null;
+            LastUseDateCal = null;
+            Nickname = null;
+        }
+
+        public String ToDebugString()
+        {
+            String retStr =
+                    "==========================\r\n" +
+                            "id  -  " + id + "\r\n" +
+                            "==========================\r\n" +
+                            "FaceID         : " + FaceID + "\r\n" +
+
+                            "RegDateCal     : " + RegDateCal.get(Calendar.YEAR) + "-" + (int)(RegDateCal.get(Calendar.MONTH)+1) + "-" + RegDateCal.get(Calendar.DAY_OF_MONTH) + "  " +
+                            RegDateCal.get(Calendar.HOUR_OF_DAY) + ":" + RegDateCal.get(Calendar.MINUTE) + ":" + RegDateCal.get(Calendar.SECOND) + "\r\n" +
+
+                            "LastUseDateCal : " + LastUseDateCal.get(Calendar.YEAR) + "-" + (int)(LastUseDateCal.get(Calendar.MONTH)+1) + "-" + LastUseDateCal.get(Calendar.DAY_OF_MONTH) + "  " +
+                            LastUseDateCal.get(Calendar.HOUR_OF_DAY) + ":" + LastUseDateCal.get(Calendar.MINUTE) + ":" + LastUseDateCal.get(Calendar.SECOND) + "\r\n" +
+
+                            "Nickname       : " + Nickname + "\r\n" +
+                            "==========================\r\n\r\n";
+            return retStr;
+        }
+    }
+
+    /**
+     * 본 클래스 생성자
+     *
+     * @param ctx - (Context)
+     */
+    public WallpadFaceIDRegData(Context ctx)
+    {
+        super(ctx);
+
+        //if(wdb!=null) wdb.execSQL("DROP TABLE " + FaceIDRegTBL);
+
+        if (!CheckTableExist(FaceIDRegTBL))
+        {
+            try
+            {
+                Log.i(TAG, "[Create] CreateFaceIDRegDB");
+                if(wdb!=null) wdb.execSQL(CreateFaceIDRegDB);
+
+                //yjyoon
+                boolean bRet = InitInsert();
+                //boolean bRet = TestInitInsert();
+
+                Log.i(TAG, "[Create] InitInsert = " + bRet);
+            }
+            catch (RuntimeException re) {
+                LogUtil.errorLogInfo("", TAG, re);
+            }
+            catch (Exception e)
+            {
+                Log.e(TAG, "[Create] Exception Error !!!");
+                //e.printStackTrace();
+                LogUtil.errorLogInfo("", TAG, e);
+            }
+        }
+    }
+
+    /**
+     * 초기화 데이터 기입
+     *
+     * @return (boolean) 성공여부 true : 성공 , false : 실패
+     */
+    private boolean InitInsert()
+    {
+        for(int i=0 ; i<255 ; i++)
+        {
+            ContentValues values = GetInitValues((int)(i+1));
+            if(wdb!=null)
+            {
+                long ret = wdb.insert(FaceIDRegTBL, null, values);
+                if(ret < 0) return false;
+            }
+
+        }
+        return true;
+    }
+
+    /**
+     * 초기화 데이터 기입
+     *
+     * @return (boolean) 성공여부 true : 성공 , false : 실패
+     */
+    private boolean TestInitInsert()
+    {
+        Log.v("yjyoon", "TestInitInsert()");
+        for(int i=0 ; i<255 ; i++)
+        {
+            ContentValues values;
+            if (i < 10)
+                values = TestGetInitValues((int)(i+1));
+            else
+                values = GetInitValues((int)(i+1));
+
+            if(wdb!=null)
+            {
+                long ret = wdb.insert(FaceIDRegTBL, null, values);
+                if(ret < 0) return false;
+            }
+
+        }
+        return true;
+    }
+
+    /**
+     * 초기화 ContentValues 기입
+     *
+     * @param id - (int) 초기화할 Id
+     *
+     * @return (ContentValues) 초기화포멧으로 기입된 ContentValues
+     */
+    private ContentValues GetInitValues(int id)
+    {
+        ContentValues values = new ContentValues();
+
+        values.put("id"   , (int)(id));
+        values.put("Used" , USED_FALSE);
+        values.put("FaceID"       , "00");
+        values.put("RegDate"      , INIT_DATE);
+        values.put("LastUseDate"  , INIT_DATE);
+        values.put("NickName" , "");
+
+        return values;
+    }
+
+    /**
+     * 초기화 ContentValues 기입
+     *
+     * @param id - (int) 초기화할 Id
+     *
+     * @return (ContentValues) 초기화포멧으로 기입된 ContentValues
+     */
+    private ContentValues TestGetInitValues(int id)
+    {
+        String nick = "";
+        ContentValues values = new ContentValues();
+
+        values.put("id"   , (int)(id));
+        if (id == 8 || id == 9) {
+            values.put("Used" , USED_FALSE);
+        } else {
+            values.put("Used" , USED_TRUE);
+        }
+
+        values.put("FaceID"       , String.format("%02X", id));
+        values.put("RegDate"      , String.format("2022:06:16:11:30:%d", id));
+        values.put("LastUseDate"  , String.format("2022:06:16:12:30:%d", id));
+        if (id == 3)
+            nick = "슈퍼맨";
+        else if (id == 4)
+            nick = "울트라맨";
+        values.put("NickName" , nick);
+
+        return values;
+    }
+
+    /**
+     * 빈 ID 를 찾는다.
+     *
+     * @return (int) - >0 : 성공, <=0 : 실패
+     */
+    public int GetEmptyId()
+    {
+        Cursor cursor = wdb.rawQuery("select id, Used from " + FaceIDRegTBL + ";", null);
+        try
+        {
+            int Used = 0;
+            while (cursor.moveToNext())
+            {
+                Used = cursor.getInt(1);
+                if(Used == USED_FALSE)
+                {
+                    int id = cursor.getInt(0);
+                    cursor.close();
+                    return id;
+                }
+            }
+            cursor.close();
+        }
+        catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            cursor.close();
+            return -100;
+        }
+        catch (Exception e)
+        {
+            cursor.close();
+            Log.e(TAG, "[GetEmptyId] Exception Error !!!");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return -100;
+        }
+        return -1;
+    }
+
+    /**
+     * FaceID 데이터를 등록한다.
+     *
+     * @param id       - (byte) 등록할 ID (*일련번호)
+     * @param FaceID   - (byte) 등록할 FaceID
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int Register(byte id, byte FaceID)
+    {
+        // 1. Param Check
+        //     1.1. id
+        if((id & 0xFF) < 1 || (id & 0xFF) > 255)
+        {
+            Log.w(TAG, "[Update] Param - id  Out Of Range !!! (id:" + id + ")");
+            return -1;
+        }
+        //     1.2. FaceID
+        if((FaceID & 0xFF) < 1 || (FaceID & 0xFF) > 255)
+        {
+            Log.w(TAG, "[Update] Param - FaceID  Out Of Range !!! (FaceID:" + FaceID + ")");
+            return -2;
+        }
+
+        // 2. 기존 등록 데이터에서 FaceID 존재유무 확인
+        int ret = 0;
+        int ExistId = isExist(FaceID);
+        if(ExistId > 0)
+        {
+            // 존재할시 삭제
+            Log.w(TAG, "[Update] isExist - Find !!! (ExistId:" + ExistId + ", FaceID:" + String.format("%02X", FaceID) + ")");
+            ret = UnRegister((byte)ExistId);
+            Log.w(TAG, "[Update] isExist - Find !!! UnRegister - ret:" + ret);
+        }
+
+        // 3. Make values
+        String whereClause = "id = " + id;
+        ContentValues values = new ContentValues();
+
+        values.put("Used"     , USED_TRUE);
+
+        values.put("FaceID"   , String.format("%02X", FaceID));
+
+        Calendar cal = new GregorianCalendar();
+        String DateStr = cal.get(Calendar.YEAR) + ":" +
+                (int)(cal.get(Calendar.MONTH)+1) + ":"+
+                cal.get(Calendar.DAY_OF_MONTH) + ":" +
+                cal.get(Calendar.HOUR_OF_DAY) + ":" +
+                cal.get(Calendar.MINUTE) + ":" +
+                cal.get(Calendar.SECOND);
+
+        values.put("RegDate"     , DateStr);
+        values.put("LastUseDate" , DateStr);
+        values.put("Nickname" , "");
+
+        // 4. update
+        ret = wdb.update(FaceIDRegTBL, values, whereClause, null);
+
+        if(ret < 0) return -10;
+
+        return 0;
+    }
+
+    /**
+     * FaceID 데이터를 등록한다.
+     *
+     * @param total       - (byte)
+     * @param FaceID   - (ArrayList<Byte>) 등록할 FaceID
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int RegisterAll (byte total, ArrayList<Byte> FaceID)
+    {
+        if ((total & 0xFF) < 1 || (total & 0xFF) > 255) {
+            Log.w(TAG, "[Update] Param - id  Out Of Range !!! (total:" + total + ")");
+            return -1;
+        }
+
+        byte faceId;
+        for (int i = 0; i < (total & 0xFF); i++) {
+
+            faceId = FaceID.get(i) ;
+
+            // 1. Param Check
+            //     1.2. FaceID
+            if ((faceId & 0xFF) < 0 || (faceId & 0xFF) > 255) {
+                Log.w(TAG, "[Update] Param - FaceID  Out Of Range !!! (FaceID:" + faceId + ")");
+                return -2;
+            }
+
+            if ((faceId & 0xFF) == 0) {
+                // 현관카메라에서 FaceID Array[50]을 전달. FaceID는 index+1 값으로 value에 저장.
+                // value = 0 이면 해당 index + 1 FaceID가 삭제되어 없다는 의미.
+                continue;
+            }
+
+            // 2. 기존 등록 데이터에서 FaceID 존재유무 확인
+            int ret = 0;
+            int ExistId = isExist(faceId);
+            if (ExistId > 0) {
+
+                // 존재할시 삭제
+                //Log.w(TAG, "[Update] isExist - Find !!! (ExistId:" + ExistId + ", FaceID:" + String.format("%02X", faceId) + ")");
+                //ret = UnRegister((byte) ExistId);
+                //Log.w(TAG, "[Update] isExist - Find !!! UnRegister - ret:" + ret);
+
+                // yjyoon. 기존 등록 데이터가 있을 경우 continue.
+                continue;
+            }
+
+            int id = ExistId > 0 ? ExistId : GetEmptyId();
+
+            // 3. Make values
+            String whereClause = "id = " + id;
+            ContentValues values = new ContentValues();
+
+            values.put("Used", USED_TRUE);
+
+            values.put("FaceID", String.format("%02X", faceId));
+
+            Calendar cal = new GregorianCalendar();
+            String DateStr = cal.get(Calendar.YEAR) + ":" +
+                    (int) (cal.get(Calendar.MONTH) + 1) + ":" +
+                    cal.get(Calendar.DAY_OF_MONTH) + ":" +
+                    cal.get(Calendar.HOUR_OF_DAY) + ":" +
+                    cal.get(Calendar.MINUTE) + ":" +
+                    cal.get(Calendar.SECOND);
+
+            values.put("RegDate", DateStr);
+            values.put("LastUseDate", DateStr);
+            values.put("Nickname", "");
+
+//            // 4. insert
+//            if(wdb.insert(FaceIDRegTBL, null, values) < 0)
+//                return -10;
+
+            // 4. update
+            ret = wdb.update(FaceIDRegTBL, values, whereClause, null);
+
+            if(ret < 0) return -10;
+        }
+
+        return 0;
+    }
+
+    /**
+     * FaceID 데이터를 삭제한다.
+     *
+     * @param id       - (byte) 등록 삭제할 ID (*일련번호)
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int UnRegister(byte id)
+    {
+        // 1. Param Check
+        //     1.1. id
+        if((id & 0xFF) < 1 || (id & 0xFF) > 255)
+        {
+            Log.w(TAG, "[Update] Param - id  Out Of Range !!! (id:" + id + ")");
+            return -1;
+        }
+
+        // 2. Make values
+        ContentValues values = GetInitValues(id & 0xFF);
+        String whereClause = "id = " + (id & 0xFF);
+
+        // 3. update
+        int ret = wdb.update(FaceIDRegTBL, values, whereClause, null);
+        if(ret < 0) return -10;
+
+        return 0;
+    }
+
+    /**
+     * 저장된 모든 FaceID 데이터를 삭제한다.
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int UnRegisterAll()
+    {
+        int ret = -1;
+        for(int i=0 ; i<255 ; i++)
+        {
+            ret = UnRegister((byte)(i+1));
+            if(ret < 0) return -100 + -((int)i);
+        }
+        return 0;
+    }
+
+    /**
+     * 저장된 FaceID 를 기준으로 Id를 찾는다.
+     *
+     * @param FaceID - (byte) 찾을 FaceID
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int FindId(byte FaceID)
+    {
+        Cursor cursor = wdb.rawQuery("select id, Used, FaceID from " + FaceIDRegTBL + ";", null);
+        try
+        {
+            int Used = 0;
+            String IdStr = String.format("%02X", FaceID);
+            while (cursor.moveToNext())
+            {
+                Used = cursor.getInt(1);
+                if(Used == USED_TRUE)
+                {
+                    if(IdStr != null && IdStr.equals(cursor.getString(2) ) )
+                    {
+                        int id = cursor.getInt(0);
+                        cursor.close();
+                        return id;
+                    }
+                }
+            }
+            cursor.close();
+        }
+        catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            cursor.close();
+            return -100;
+        }
+        catch (Exception e)
+        {
+            cursor.close();
+            Log.e(TAG, "[FindId] Exception Error !!!");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return -100;
+        }
+        return -1;
+    }
+
+    /**
+     * 최근사용일자 갱신
+     *
+     * @param id  - (byte) 갱신할 ID (*일련번호)
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int UpdateLastUseDate(byte id)
+    {
+        // 1. Param Check
+        //     1.1. id
+        if((id & 0xFF) < 1 || (id & 0xFF) > 255)
+        {
+            Log.w(TAG, "[Update] Param - id  Out Of Range !!! (id:" + id + ")");
+            return -1;
+        }
+
+        // 2. Make values
+        String whereClause = "id = " + (id & 0xFF);
+        ContentValues values = new ContentValues();
+
+        Calendar cal = new GregorianCalendar();
+        String DateStr = cal.get(Calendar.YEAR) + ":" +
+                (int)(cal.get(Calendar.MONTH)+1) + ":"+
+                cal.get(Calendar.DAY_OF_MONTH) + ":" +
+                cal.get(Calendar.HOUR_OF_DAY) + ":" +
+                cal.get(Calendar.MINUTE) + ":" +
+                cal.get(Calendar.SECOND);
+
+        values.put("LastUseDate" , DateStr);
+
+        // 3. update
+        int ret = wdb.update(FaceIDRegTBL, values, whereClause, null);
+
+        if(ret < 0) return -10;
+
+        return 0;
+    }
+
+    /**
+     * FaceID 를 기준으로 등록 존재 여부를 체크한다.
+     *
+     * @param FaceID - (byte) 찾을 FaceID
+     *
+     * @return (int) - >=1 : 성공 (등록된 id 반환), =<0 : 실패
+     */
+    public int isExist(byte FaceID)
+    {
+        // 1. Param Check
+        //     1.1. FaceID
+        if((FaceID & 0xFF) < 1 || (FaceID & 0xFF) > 255)
+        {
+            Log.w(TAG, "[isExist] Param - FaceID  Out Of Range !!! (FaceID:" + FaceID + ")");
+            return -10;
+        }
+
+        // 2. Find
+        Cursor cursor = wdb.rawQuery("select id, Used, FaceID from " + FaceIDRegTBL + ";", null);
+        try
+        {
+            int Used = 0;
+            String nIdStr = String.format("%02X", FaceID);
+            String IdStr = null;
+            while (cursor.moveToNext())
+            {
+                Used = cursor.getInt(1);
+                if(Used == USED_TRUE)
+                {
+                    IdStr = cursor.getString(2);
+                    if(nIdStr != null && IdStr != null && nIdStr.equals(IdStr))
+                    {
+                        int id = cursor.getInt(0);
+                        return id;
+                    }
+                }
+            }
+            cursor.close();
+
+            return -1;      // Not Find
+        }
+        catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            cursor.close();
+            SyncData.clear();
+            return -100;
+        }
+        catch (Exception e)
+        {
+            cursor.close();
+            SyncData.clear();
+            Log.e(TAG, "[isExist] Exception Error");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return -100;
+        }
+    }
+
+    /**
+     * FaceID 명칭을 가져온다.
+     *
+     * @param FaceID - (byte) 찾을 FaceID
+     *
+     * @return (String) - null : 실패
+     */
+    public String getNickname(byte FaceID)
+    {
+        // 1. Param Check
+        //     1.1. FaceID
+        if((FaceID & 0xFF) < 1 || (FaceID & 0xFF) > 255)
+        {
+            Log.w(TAG, "[getNickname] Param - FaceID  Out Of Range !!! (FaceID:" + FaceID + ")");
+            return null;
+        }
+
+        // 2. Find
+        Cursor cursor = wdb.rawQuery("select id, Used, FaceID, Nickname from " + FaceIDRegTBL + ";", null);
+        try
+        {
+            int Used = 0;
+            String nIdStr = String.format("%02X", FaceID);
+            String IdStr = null;
+            while (cursor.moveToNext())
+            {
+                Used = cursor.getInt(1);
+                if(Used == USED_TRUE)
+                {
+                    IdStr = cursor.getString(2);
+                    if(nIdStr != null && IdStr != null && nIdStr.equals(IdStr))
+                    {
+                        String id = cursor.getString(3);
+                        return id;
+                    }
+                }
+            }
+            cursor.close();
+
+            return null;      // Not Find
+        }
+        catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            cursor.close();
+            SyncData.clear();
+            return null;
+        }
+        catch (Exception e)
+        {
+            cursor.close();
+            SyncData.clear();
+            Log.e(TAG, "[getNickname] Exception Error");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+    }
+
+    /**
+     * FaceID 명칭을 설정한다.
+     *
+     * @param FaceID   - (byte) 명칭을 설정할 FaceID
+     * @param NewNickname   - (String) 설정할 명칭
+     *
+     * @return (int) - >=0 : 성공, <0 : 실패
+     */
+    public int SetNickname(byte FaceID, String NewNickname)
+    {
+        // 1. Param Check
+        //     1.1. FaceID
+        if((FaceID & 0xFF) < 1 || (FaceID & 0xFF) > 255)
+        {
+            Log.w(TAG, "[SetNickname] Param - FaceID  Out Of Range !!! (FaceID:" + FaceID + ")");
+            return -2;
+        }
+        //     1.2. NewNickname
+        if(NewNickname == null)
+        {
+            Log.w(TAG, "[SetNickname] Param - NewNickname is NULL !!!");
+            return -3;
+        }
+
+        // 2. 기존 등록 데이터에서 FaceID 존재유무 확인
+        int ret = 0;
+        int ExistId = isExist(FaceID);
+        if(ExistId > 0)
+        {
+            // 존재할시 삭제
+            Log.w(TAG, "[SetNickname] isExist - Find !!! (ExistId:" + ExistId + ", FaceID:" + String.format("%02X", FaceID) + ")");
+            ret = UnRegister((byte)ExistId);
+            Log.w(TAG, "[SetNickname] isExist - Find !!! UnRegister - ret:" + ret);
+        }
+
+        // 3. Make values
+        String whereClause = "id = " + ExistId;
+        ContentValues values = new ContentValues();
+
+        values.put("Used"     , USED_TRUE);
+
+        values.put("FaceID"   , String.format("%02X", FaceID));
+
+        Calendar cal = new GregorianCalendar();
+        String DateStr = cal.get(Calendar.YEAR) + ":" +
+                (int)(cal.get(Calendar.MONTH)+1) + ":"+
+                cal.get(Calendar.DAY_OF_MONTH) + ":" +
+                cal.get(Calendar.HOUR_OF_DAY) + ":" +
+                cal.get(Calendar.MINUTE) + ":" +
+                cal.get(Calendar.SECOND);
+
+        values.put("RegDate"     , DateStr);
+        values.put("LastUseDate" , DateStr);
+        values.put("Nickname" , NewNickname);
+
+        // 4. update
+        ret = wdb.update(FaceIDRegTBL, values, whereClause, null);
+
+        if(ret < 0) return -10;
+
+        return 0;
+    }
+
+    /**
+     * 등록되어있는 FaceID 데이터 List 를 반환한다.
+     *
+     * @return (List<FaceIDDataClass>) 등록 데이터 List
+     */
+    public List<FaceIDDataClass> GetFaceIDRegData()
+    {
+        Cursor cursor = wdb.rawQuery("select id, Used, FaceID, RegDate, LastUseDate, Nickname from " + FaceIDRegTBL + " ORDER BY FaceID ASC;", null);
+        try
+        {
+            SyncData.clear();
+            int Used = 0;
+            String RegDateStr = null;
+            String LastUseDateStr = null;
+            int testI = 0;
+            while (cursor.moveToNext())
+            {
+                Used = cursor.getInt(1);
+                if(Used == USED_TRUE)
+                {
+                    FaceIDDataClass getdata = new FaceIDDataClass();
+
+                    getdata.id             = cursor.getInt(0);
+                    getdata.FaceID         = cursor.getString(2);
+                    RegDateStr             = cursor.getString(3);
+                    LastUseDateStr         = cursor.getString(4);
+                    getdata.Nickname       = cursor.getString(5);
+
+                    testI++;
+
+                    String[] retData = null;
+
+                    retData = RegDateStr.split(":");
+                    if(retData != null)
+                    {
+                        if(retData.length >= 6)
+                        {
+                            getdata.RegDateCal = new GregorianCalendar();
+                            getdata.RegDateCal.set(Calendar.YEAR, Integer.parseInt(retData[0]));
+                            getdata.RegDateCal.set(Calendar.MONTH, Integer.parseInt(retData[1])-1);
+                            getdata.RegDateCal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(retData[2]));
+                            getdata.RegDateCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(retData[3]));
+                            getdata.RegDateCal.set(Calendar.MINUTE, Integer.parseInt(retData[4]));
+                            getdata.RegDateCal.set(Calendar.SECOND, Integer.parseInt(retData[5]));
+                        }
+                    }
+                    retData = LastUseDateStr.split(":");
+                    if(retData != null)
+                    {
+                        if(retData.length >= 6)
+                        {
+                            getdata.LastUseDateCal = new GregorianCalendar();
+                            getdata.LastUseDateCal.set(Calendar.YEAR, Integer.parseInt(retData[0]));
+                            getdata.LastUseDateCal.set(Calendar.MONTH, Integer.parseInt(retData[1])-1);
+                            getdata.LastUseDateCal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(retData[2]));
+                            getdata.LastUseDateCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(retData[3]));
+                            getdata.LastUseDateCal.set(Calendar.MINUTE, Integer.parseInt(retData[4]));
+                            getdata.LastUseDateCal.set(Calendar.SECOND, Integer.parseInt(retData[5]));
+                        }
+                    }
+
+                    SyncData.add(getdata);
+                }
+            }
+            cursor.close();
+        }
+        catch (RuntimeException re) {
+            LogUtil.errorLogInfo("", TAG, re);
+            cursor.close();
+            SyncData.clear();
+            return null;
+        }
+        catch (Exception e)
+        {
+            cursor.close();
+            SyncData.clear();
+            Log.e(TAG, "[GetFaceIDRegData] Exception Error");
+            //e.printStackTrace();
+            LogUtil.errorLogInfo("", TAG, e);
+            return null;
+        }
+        return SyncData;
+    }
+
+
+    /**
+     *
+     * @param in
+     *
+     * @return
+     */
+    private static String GetByteStringFormat(byte [] in)
+    {
+        if(in == null) return null;
+        if(in.length != 4) return null;
+
+        return String.format("%02X%02X%02X%02X", in[0], in[1], in[2], in[3]);
+    }
+
+    public String ToDebugFaceIDData(List<FaceIDDataClass> data)
+    {
+        String retstr;
+
+        retstr  = "-----------------------------\r\n";
+        retstr += "FaceIDData\r\n";
+        retstr += "-----------------------------\r\n";
+
+        if(data.isEmpty())
+        {
+            retstr += "Empty ...\r\n";
+            retstr += "-----------------------------\r\n";
+            return retstr;
+        }
+        else
+        {
+            for(int i=0 ; i<data.size() ; i++)
+            {
+                FaceIDDataClass getData = data.get(i);
+                if(getData != null)
+                {
+                    retstr += getData.ToDebugString();
+                }
+            }
+            retstr += "-----------------------------\r\n";
+        }
+
+        return retstr;
+    }
+
+    public int GetCount() {
+        Cursor cursor = wdb.rawQuery("select id, Used from " + FaceIDRegTBL + ";", null);
+
+        try {
+            int i = 0;
+            int Used;
+            while(cursor.moveToNext()){
+                Used = cursor.getInt(1);
+                if(Used == USED_TRUE)
+                {
+                    i++;
+                }
+            }
+            cursor.close();
+            return i;
+        } catch (RuntimeException var6) {
+            LogUtil.errorLogInfo("", "WallpadSmartKeyRegData", var6);
+            cursor.close();
+            return -100;
+        } catch (Exception var7) {
+            cursor.close();
+            Log.e("WallpadSmartKeyRegData", "[GetCount] Exception Error !!!");
+            LogUtil.errorLogInfo("", "WallpadSmartKeyRegData", var7);
+            return -100;
+        }
+    }
+}
+

+ 85 - 0
WallPadAPI/src/main/java/com/artncore/WallPadDataMgr/WallpadStatusData.java

@@ -833,6 +833,9 @@ public class WallpadStatusData extends wallpaddbmgr {
 	/** 스마트키 감지시 알람 (사운드 및 토스트메시지) */
 	public static final String SMARTKEY_DETECTION_ALARM  = "SMARTKEY_DETECTION_ALARM";
 
+	/** FaceID 감지시 알람 (사운드 및 토스트메시지) */
+	public static final String FACEID_DETECTION_ALARM  = "FACEID_DETECTION_ALARM";
+
 	/** 환기 예약 ON/OFF */
 	public static final String VEN_RESERVE_ONOFF  = "VEN_RESERVE_ONOFF";
 
@@ -6564,4 +6567,86 @@ public class WallpadStatusData extends wallpaddbmgr {
 			LogUtil.errorLogInfo("", TAG, e);//e.printStackTrace();
 		}
 	}
+
+	/**
+	 * 안면인식 현관폰 - 안면인식 사용 여부 읽기
+	 *
+	 * @return (String) 안면인식 정책
+	 */
+	public String GetFacialRecognitionPolicy() {
+		try {
+			String strRet = GetWallPADData(FACIAL_RECOGNITION_POLICY);
+			Log.d(TAG, "[GetFacialRecognitionPolicy] strRet [" + strRet + "]");
+			if (strRet == null) {
+				Log.d(TAG, "[GetFacialRecognitionPolicy] strRet is null !!");
+				insertWallPADDB(FACIAL_RECOGNITION_POLICY, FACIAL_RECOGNITION_POLICY_DEFAULT);
+				strRet = FACIAL_RECOGNITION_POLICY_DEFAULT;
+			}
+
+			return strRet;
+		} catch (RuntimeException re) {
+			LogUtil.errorLogInfo("", TAG, re);
+			return FACIAL_RECOGNITION_POLICY_DEFAULT; // DB 값 접근 에러 발생시, 디폴트값으로 설정
+		} catch (Exception e) {
+			Log.e(TAG, "[GetFacialRecognitionPolicy] Exception Error");
+			LogUtil.errorLogInfo("", TAG, e);//e.printStackTrace();
+			return FACIAL_RECOGNITION_POLICY_DEFAULT; // DB 값 접근 에러 발생시, 디폴트값으로 설정
+		}
+	}
+
+	public static final String FACIAL_RECOGNITION_POLICY  = "FACIAL_RECOGNITION_POLICY";
+	public static final String FACIAL_RECOGNITION_POLICY_DEFAULT = "1|0|5|3|10|0|0|0|30|5|0|0|0";
+
+	/**
+	 * FaceID 감지시 알람 여부 읽기
+	 *
+	 * @return (boolean) 설정값 (true:ON , false:OFF)
+	 */
+	public boolean GetFaceIDDetectionAlarm()
+	{
+		try
+		{
+			String ret = GetWallPADData(FACEID_DETECTION_ALARM);
+
+			if(ret.compareTo(String.valueOf(true)) == 0)
+			{
+				return true;
+			}
+			else
+			{
+				return false;
+			}
+		}
+		catch (RuntimeException re) {
+			LogUtil.errorLogInfo("", TAG, re);
+			return false;
+		}
+		catch (Exception e )
+		{
+			Log.e(TAG, "[GetFaceIDDetectionAlarm] Exception Error");
+			LogUtil.errorLogInfo("", TAG, e);//e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * FaceID 감지시 알람 여부 설정
+	 *
+	 * @param bSet - (boolean) 설정할 값 (true:ON , false:OFF)
+	 */
+	public void SetFaceIDDetectionAlarm(boolean bSet)
+	{
+		try
+		{
+			UpdateWallPADData(FACEID_DETECTION_ALARM, String.valueOf(bSet));
+		}
+		catch (RuntimeException re) {
+			LogUtil.errorLogInfo("", TAG, re);
+		}
+		catch (Exception e)
+		{
+			Log.e(TAG, "[SetFaceIDDetectionAlarm] Exception Error");
+			LogUtil.errorLogInfo("", TAG, e);//e.printStackTrace();
+		}
+	}
 }

+ 2 - 0
WallPadAPI/src/main/java/com/artncore/WallPadDataMgr/wallpaddbmgr.java

@@ -53,6 +53,7 @@ public class wallpaddbmgr {
     public static  final String VersionTBL     = "VersionDB";
     public static  final String RealTimeMeterTBL = "RealTimeMeterDB";
     public static  final String SmartKeyRegTBL   = "SmartKeyRegDB";
+    public static  final String FaceIDRegTBL      = "FaceIDRegDB";
     public static  final String AccessTBL        = "AccessDB";
     public static  final String CarEventTBL      = "CarEventDB";
     public static  final String LH_GatewayTBL    = "LH_GatewayDB";
@@ -91,6 +92,7 @@ public class wallpaddbmgr {
     protected static final String CreateMobileDeviceDB  = "create table " + MobileDeviceTBL  + " (seqnum INTEGER PRIMARY KEY AUTOINCREMENT, uid text, name text, regdate DATE DEFAULT (datetime('now','localtime')));";
     protected static final String CreateSmartConcentAccSaveDB  = "create table " + SmartConcentAccSaveTBL  + " (num INTEGER unique, concentcount INTEGER, value text);";
     protected static final String CreateRemoteCallUserDB = "create table " + RemoteCallUserTBL + " (seqnum INTEGER PRIMARY KEY AUTOINCREMENT, PHONE_KEY text, NAME text, MONITOR_AUTH text, LOBBY_OPEN text, DOOR_OPEN text, HOME_VIEWER text);";
+    protected static final String CreateFaceIDRegDB     = "create table " + FaceIDRegTBL  + " (id INTEGER unique, Used INTEGER, FaceID text, RegDate text, LastUseDate text, Nickname text);";
 
 
     private AddressSet AddressMGR;

+ 91 - 0
WallPadAPI/src/main/java/com/artncore/commons/DataClasses.java

@@ -7319,4 +7319,95 @@ public class DataClasses {
             }
         }
     }
+
+
+    /////////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+    /** [안면인식 현관폰]  정책 데이터 클래스*/
+    /////////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+    public static class FacialRecogPolicy {
+        /** 안면인식 사용 (0:사용안함, 1:사용함)*/
+        public int nRecognitionUsage;
+        /** 거동수상자 감지 (0:사용안함, 1:사용함)*/
+        public int nDetect;
+        /** 모자/마스크 허용 (0:허용안함, 1:허용함)*/
+        public int nHatMask;
+        /** 안면 트래커 출력 (0:출력안함, 1:출력함)*/
+        public int nTracker;
+        /** 복수 안면인식 허용 (0:허용안함, 1:허용함)*/
+        public int nMultipleRecognition;
+        /** 복수 승인 조건 (0:AND조건, 1:OR조건)*/
+        public int nCondition;
+
+        /** 안면인식 감도 (1 ~ 5)*/
+        public int nSensitivity;
+        /** 안면인식 거리 (1 ~ 5)*/
+        public int nDistance;
+        /** 거동수상자 감지 기준 시간 (3 ~ 20)*/
+        public int nDetectTime;
+        /** 거동수상자 감지 기준 횟수 (0 ~ 15)*/
+        public int nDetectCount;
+
+        /** 카메라 AE 모드 (0:사용안함, 1:사용함)*/
+        public int Door_AEMode;
+        /** 현관폰 절전모드 (5 ~ 180) */
+        public int Door_EcoMode;
+        /** 현관폰 재부팅 (0:즉시 재부팅, 1: 대기중 재부팅)*/
+        public int Door_RebootMode;
+        /** 현관폰 메시지 출력 (0:사용안함, 1:사용함)*/
+        public int Door_Display_Message;
+        /** 현관폰 메시지*/
+        public String Door_Message;
+
+        /** 거동수상자 녹화시간 (10 ~ 30)*/
+        public int nStrangeRecordTime;
+
+        public FacialRecogPolicy() {
+            nRecognitionUsage = 1;      // 사용함
+            nDetect = 0;                // 사용안함
+            nHatMask = 0;               // 허용안함
+            nTracker = 0;               // 사용안함
+            nMultipleRecognition = 0;   // 허용안함
+            nCondition = 0;             // AND조건(0)
+
+            nSensitivity = 5;           // 5단계
+            nDistance = 3;              // 3단계
+            nDetectTime = 5;            // 5초
+            nDetectCount = 0;           // 안면인식현관폰에서 미사용
+
+            Door_AEMode = 0;            // 사용안함
+            Door_EcoMode = 10;          // 10초
+            Door_RebootMode = -1;
+            Door_Display_Message = 0;   // 사용안함
+            Door_Message = "";
+
+            nStrangeRecordTime = 30;    // 30초
+        }
+
+        public String ToDebugString() {
+            String retStr =
+                    "==========================\r\n" +
+                            "InfoFacialRecognitionConfig\r\n" +
+                            "==========================\r\n" +
+                            "nRecognitionUsage    : " + nRecognitionUsage + "\r\n" +
+                            "nDetect              : " + nDetect + "\r\n" +
+                            "nHatMask             : " + nHatMask + "\r\n" +
+                            "nTracker             : " + nTracker + "\r\n" +
+                            "nMultipleRecognition : " + nMultipleRecognition + "\r\n" +
+                            "nCondition           : " + nCondition + "\r\n" +
+                            "nSensitivity         : " + nSensitivity + "\r\n" +
+                            "nDistance            : " + nDistance + "\r\n" +
+                            "nDetectTime          : " + nDetectTime + "\r\n" +
+                            "nDetectCount         : " + nDetectCount + "\r\n" +
+                            "nStrangeRecordTime   : " + nStrangeRecordTime + "\r\n" +
+                            "Door_AEMode          : " + Door_AEMode + "\r\n" +
+                            "Door_EcoMode         : " + Door_EcoMode + "\r\n" +
+                            "Door_RebootMode      : " + Door_RebootMode + "\r\n" +
+                            "Door_Display_Message : " + Door_Display_Message + "\r\n" +
+                            "Door_Message         : " + Door_Message + "\r\n" +
+                            "==========================";
+            return retStr;
+        }
+    }
 }

+ 9 - 0
WallPadAPI/src/main/java/com/artncore/commons/define.java

@@ -290,6 +290,12 @@ public class define {
 	public static final int NOTIFY_ACCEPT_TAKEPIC_STRANGER = 1607; // 거동수상자 알림 팝업에서 거동수상자 촬영 승인
 	public static final int NOTIFY_REJECT_TAKEPIC_STRANGER = 1608; // 거동수상자 알림 팝업에서 거동수상자 촬영 거절
 	public static final int NOTIFY_FINISH_TAKEPIC_STRANGER = 1609; // 거동수상자 촬영 종료
+	public static final int NOTIFY_DOORLOCK_OPEN_RECORDING = 1610; // 거동수상자 녹화 중 문열림 알림
+	public static final int NOTIFY_FRONTCALL_END_RECORDING = 1611; // 거동수상자 녹화 중 현관통화 종료 알림
+	public static final int NOTIFY_GUARD_OUT_RECORDING = 1612; // 외출방범중 거동수상자 녹화 알림
+	public static final int NOTIFY_FACIAL_RECOG_AUTH = 1613; // 안면인식 인증 알림
+	public static final int NOTIFY_OPEN_DOOR = 1614; // 안면인식 인증에 의한 문열림 알림
+	public static final int NOTIFY_SMART_DCAM_DETECT_MODE  	  = 1615;	// jglee - 거동수상자 감지 시, 관리자 설정에서 단순 테스트를 위해 BR 추가(관리자모드에서 거동수상자 감지 됬다고 녹화가 올라가는것을 방지 하귀 위한 것)
 
 	/** 층간소음 발생 알림 **/
 	public static final int NOTIFY_INTERLAYTER_NOISE_ALARM 			= 1700;
@@ -714,6 +720,9 @@ public class define {
 	public static final String DEVICE_ID_MAIN_GUI_CTRL_USE = "제어기능";
 	public static final String DEVICE_ID_DOOROPEN_WAIT_TIME = "문열림대기시간";
 
+	public static final String DEVICE_ID_SMARTCAM_DURATION = "거동수상자감지시간";  // jglee - 2023.03.29 거동수상자 시나리오 변경에 따른 DB 추가
+	public static final String DEVICE_ID_SMARTCAM_COUNT = "거동수상자감지횟수"; // jglee - 2023.03.29 거동수상자 시나리오 변경에 따른 DB 추가
+
 	public static final String DEVICE_ENABLE  = "사용함";
 	public static final String DEVICE_DISABLE = "사용안함";