Browse Source

[New feature][Modularization][Module_Wifi]

2020.09.15 / Folus Wen

Actions:
1. EVSE/Modularization/Makefile modify Module_Wifi compile command for add JSON-C lib.
2. EVSE/Projects/define.h add struct Schedule to struct Charging_Info.
3. EVSE/Modularization/Module_Wifi.c implement schedule charging function.

Files:
1. As follow commit history

Image version: D0.00.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 4 years ago
parent
commit
6bc85103e8
3 changed files with 675 additions and 38 deletions
  1. 2 2
      EVSE/Modularization/Makefile
  2. 653 30
      EVSE/Modularization/Module_Wifi.c
  3. 20 6
      EVSE/Projects/define.h

+ 2 - 2
EVSE/Modularization/Makefile

@@ -35,8 +35,8 @@ Module_RFIDLib:
 
 Module_Wifi:
 	rm -f Module_Wifi
-	$(CC) -D $(Project) -I ../Projects -I .//ocppfiles -O0 -g3 -Wall -c -fmessage-length=0 -o Module_Wifi.o Module_Wifi.c
-	$(CC) -o Module_Wifi Module_Wifi.o ${Lib_SQLite3}
+	$(CC) -D $(Project) -I ../Projects -I .//ocppfiles -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -O0 -g3 -Wall -c -fmessage-length=0 -o Module_Wifi.o Module_Wifi.c
+	$(CC) -o Module_Wifi Module_Wifi.o ${Lib_SQLite3} -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -ljson-c
 	rm -f Module_Wifi.o
 	mv -f Module_Wifi ../rootfs/root
 

+ 653 - 30
EVSE/Modularization/Module_Wifi.c

@@ -42,6 +42,7 @@
 #include	<ctype.h>
 #include 	<ifaddrs.h>
 #include	<sqlite3.h>
+#include	<json-c/json.h>
 #include    <signal.h>
 #include	"define.h"
 
@@ -49,6 +50,7 @@
 #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 
+#define is_error(ptr) 				((unsigned long)ptr > (unsigned long)-4000L)
 #define ARRAY_SIZE(A)				(sizeof(A) / sizeof(A[0]))
 #define PASS						1
 #define FAIL			   			-1
@@ -94,7 +96,8 @@
 
 #define DEBUG
 
-#define DB_FILE						"/Storage/ChargeLog/puk_pin_list.db"
+#define DB_FILE_PUK					"/Storage/ChargeLog/puk_pin_list.db"
+#define DB_FILE_CHARGING			"/Storage/ChargeLog/localCgargingRecord.db"
 
 enum WIFI_COMMAND
 {
@@ -550,10 +553,10 @@ int getInterfaceInfo()
 			if(strstr(buf, "inet addr:") > 0)
 			{
 				sscanf(buf, "%*s%s", tmp);
-				substr(Wifi.currentIPAddr, tmp, strspn(tmp, "addr:"), strlen(buf)-strspn(tmp, "addr:"));
+				substr(Wifi.currentIPAddr, tmp, strspn(tmp, "addr:"), strlen(tmp)-strspn(tmp, "addr:"));
 
 				sscanf(buf, "%*s%*s%*s%s", tmp);
-				substr(Wifi.currentNetmask, tmp, strspn(tmp, "Mask:"), strlen(buf)-strspn(tmp, "Mask:"));
+				substr(Wifi.currentNetmask, tmp, strspn(tmp, "Mask:"), strlen(tmp)-strspn(tmp, "Mask:"));
 			}
 		}
 	}
@@ -1095,7 +1098,7 @@ int DB_Open(sqlite3 *db)
 					");";
 
 	//sqlite3_config(SQLITE_CONFIG_URI, 1);
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1130,7 +1133,7 @@ uint8_t isPukReg(sqlite3 *db)
 	sprintf(sqlStr, "select * from list where list_type='puk';");
 	DEBUG_INFO("sqlStr= %s\n", sqlStr);
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1163,7 +1166,7 @@ uint8_t PukReg(sqlite3 *db)
 					wifi_login_info.loginId);
 	DEBUG_INFO("sqlStr= %s\n", sqlStr);
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1198,7 +1201,7 @@ uint8_t isPinGen(sqlite3 *db)
 	sprintf(sqlStr, "select * from list where list_type='pin';");
 	DEBUG_INFO("sqlStr= %s\n", sqlStr);
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1226,7 +1229,7 @@ uint8_t PinGen(sqlite3 *db)
 	char sqlStr[1024];
 	srand(time(NULL));
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1280,7 +1283,7 @@ uint8_t isValidPin(sqlite3 *db, uint8_t *pinCode)
 	sprintf(sqlStr, "select * from list where list_type='pin' and code='%s';", pinCode);
 	DEBUG_INFO("sqlStr= %s\n", sqlStr);
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1313,7 +1316,7 @@ uint8_t loginValid(sqlite3 *db)
 	DEBUG_INFO("sqlStr= %s\n", sqlStr);
 	DEBUG_INFO("Login id: %s\n", wifi_login_info.loginId);
 
-	if(sqlite3_open(DB_FILE, &db))
+	if(sqlite3_open(DB_FILE_PUK, &db))
 	{
 		result = FAIL;
 		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
@@ -1345,6 +1348,209 @@ uint8_t loginValid(sqlite3 *db)
 	return result;
 }
 
+int cbScheduleSave(void *para, int columnCount, char **columnValue, char **columnName)
+{
+	DEBUG_INFO("Config schedule callback.\n");
+	for(int i=0; i<columnCount; i++)
+	{
+	      DEBUG_INFO("%s = %s\n", columnName[i], columnValue[i] ? columnValue[i] : "NULL");
+	}
+
+	return 0;
+}
+
+uint8_t scheduleSaveToDb(sqlite3 *db, uint8_t gun_index, struct Schedule *schedule)
+{
+	 int result = PASS;
+	 char* errMsg = NULL;
+	 char sqlStr[512];
+	 json_object *scheduleObj = json_object_new_object();
+
+	 // Save config to local db file
+	json_object_object_add(scheduleObj, "isEnable", json_object_new_int(schedule->isEnable));
+	json_object_object_add(scheduleObj, "scheduleType", json_object_new_int(schedule->scheduleType));
+	json_object_object_add(scheduleObj, "scheduleMethod", json_object_new_int(schedule->scheduleMethod));
+	json_object_object_add(scheduleObj, "startTimeHour", json_object_new_int(schedule->startTimeHour));
+	json_object_object_add(scheduleObj, "startTimeMinute", json_object_new_int(schedule->startTimeMinute));
+	json_object_object_add(scheduleObj, "stopTimeHour", json_object_new_int(schedule->stopTimeHour));
+	json_object_object_add(scheduleObj, "stopTimeMinute", json_object_new_int(schedule->stopTimeMinute));
+	sprintf((char*)sqlStr, "insert or replace into config (item, connector, val) VALUES('schedule', %d, '%s');  SELECT * from config;", gun_index, json_object_to_json_string(scheduleObj));
+
+	 //* Execute SQL statement */
+	 if(sqlite3_open(DB_FILE_CHARGING, &db))
+	{
+		result = FAIL;
+		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
+		sqlite3_close(db);
+	}
+	else
+	{
+		if(sqlite3_exec(db, (char*)sqlStr, cbScheduleSave, 0, &errMsg) != SQLITE_OK)
+		 {
+			 DEBUG_INFO("SQL error: %s\n", errMsg);
+			 result = FAIL;
+		 }
+		sqlite3_close(db);
+	}
+
+	return result;
+}
+
+int cbScheduleLoad(void *para, int columnCount, char **columnValue, char **columnName)
+{
+	uint8_t gun_index;
+	uint8_t idxAC = 0;
+	uint8_t idxCCS = 0;
+	uint8_t idxCHAdeMO = 0;
+	uint8_t idxGBT = 0;
+	uint8_t AC_GUN_IDX = 0;
+	json_object *scheduleObj = json_tokener_parse(columnValue[3]);
+
+	DEBUG_INFO("Query schedule callback.\n");
+	for(int i=0; i<columnCount; i++)
+	{
+	      DEBUG_INFO("%s = %s\n", columnName[i], columnValue[i] ? columnValue[i] : "NULL");
+	}
+
+	if((columnCount>0) && !is_error(scheduleObj))
+	{
+		gun_index = atoi(columnValue[2]);
+
+		if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'A')
+		{
+			if(gun_index == 2)
+			{
+				AC_GUN_IDX = 0;
+			}
+			else if(gun_index == 1)
+			{
+				AC_GUN_IDX = 1;
+			}
+			else if(gun_index == 0)
+			{
+				AC_GUN_IDX = 2;
+			}
+
+			for(uint8_t idx=0;idx<AC_GUN_IDX;idx++)
+			{
+				switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-idx])
+				{
+					case '1' ... '6':
+						idxAC++;
+						break;
+				}
+			}
+
+			switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-AC_GUN_IDX])
+			{
+				case '1' ... '6':
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable = json_object_get_int(json_object_object_get(scheduleObj, "isEnable"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType = json_object_get_int(json_object_object_get(scheduleObj, "scheduleType"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod = json_object_get_int(json_object_object_get(scheduleObj, "scheduleMethod"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "startTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "startTimeMinute"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeMinute"));
+					break;
+			}
+		}
+		else if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'D')
+		{
+			for(uint8_t idx=0;idx<gun_index;idx++)
+			{
+				switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+idx])
+				{
+					case '1' ... '6':
+						idxAC++;
+						break;
+					case 'J':
+						idxCHAdeMO++;
+						break;
+					case 'U':
+					case 'E':
+						idxCCS++;
+						break;
+					case 'G':
+						idxGBT++;
+						break;
+				}
+			}
+
+			switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
+			{
+				case '1' ... '6':
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable = json_object_get_int(json_object_object_get(scheduleObj, "isEnable"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType = json_object_get_int(json_object_object_get(scheduleObj, "scheduleType"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod = json_object_get_int(json_object_object_get(scheduleObj, "scheduleMethod"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "startTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "startTimeMinute"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeMinute"));
+					break;
+				case 'J':
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isEnable = json_object_get_int(json_object_object_get(scheduleObj, "isEnable"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleType = json_object_get_int(json_object_object_get(scheduleObj, "scheduleType"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleMethod = json_object_get_int(json_object_object_get(scheduleObj, "scheduleMethod"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "startTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "startTimeMinute"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeMinute"));
+					break;
+				case 'U':
+				case 'E':
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isEnable = json_object_get_int(json_object_object_get(scheduleObj, "isEnable"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleType = json_object_get_int(json_object_object_get(scheduleObj, "scheduleType"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleMethod = json_object_get_int(json_object_object_get(scheduleObj, "scheduleMethod"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "startTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "startTimeMinute"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeMinute"));
+					break;
+				case 'G':
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isEnable = json_object_get_int(json_object_object_get(scheduleObj, "isEnable"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleType = json_object_get_int(json_object_object_get(scheduleObj, "scheduleType"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleMethod = json_object_get_int(json_object_object_get(scheduleObj, "scheduleMethod"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "startTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "startTimeMinute"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeHour"));
+					ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute = json_object_get_int(json_object_object_get(scheduleObj, "stopTimeMinute"));
+					break;
+			}
+		}
+	}
+	json_object_put(scheduleObj);
+
+	return 0;
+}
+
+uint8_t scheduleLoadFromDb(sqlite3 *db, uint8_t gun_index)
+{
+	 int result = PASS;
+	 char* errMsg = NULL;
+	 char sqlStr[512];
+
+	 sprintf(sqlStr, "select * from config where item='schedule' and connector=%d", gun_index);
+
+	 //* Execute SQL statement */
+	 if(sqlite3_open(DB_FILE_CHARGING, &db))
+	{
+		result = FAIL;
+		DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db));
+		sqlite3_close(db);
+	}
+	else
+	{
+		if(sqlite3_exec(db, sqlStr, cbScheduleLoad, 0, &errMsg) != SQLITE_OK)
+		 {
+			 DEBUG_INFO("SQL error: %s\n", errMsg);
+			 result = FAIL;
+		 }
+		sqlite3_close(db);
+	}
+
+	return result;
+}
+
 //==========================================
 // TCP socket server routine
 //==========================================
@@ -1634,6 +1840,8 @@ void getConnectorSchedule(uint8_t gun_index, uint8_t *outBuffer)
 	uint8_t idxCHAdeMO = 0;
 	uint8_t idxGBT = 0;
 	uint8_t AC_GUN_IDX = 0;
+
+	scheduleLoadFromDb(localDb, gun_index);
 	
 	if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'A')
 	{
@@ -1649,7 +1857,7 @@ void getConnectorSchedule(uint8_t gun_index, uint8_t *outBuffer)
 		{
 			AC_GUN_IDX = 2;
 		}
-		
+
 		for(uint8_t idx=0;idx<AC_GUN_IDX;idx++)
 		{
 			switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-idx])
@@ -1659,6 +1867,19 @@ void getConnectorSchedule(uint8_t gun_index, uint8_t *outBuffer)
 					break;
 			}
 		}
+
+		switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-AC_GUN_IDX])
+		{
+			case '1' ... '6':
+				outBuffer[6] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable;
+				outBuffer[7] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType;
+				outBuffer[8] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod;
+				outBuffer[9] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour;
+				outBuffer[10] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute;
+				outBuffer[11] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour;
+				outBuffer[12] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute;
+				break;
+		}
 	}
 	else if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'D')
 	{
@@ -1681,12 +1902,48 @@ void getConnectorSchedule(uint8_t gun_index, uint8_t *outBuffer)
 					break;
 			}
 		}
+
+		switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
+		{
+			case '1' ... '6':
+				outBuffer[6] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable;
+				outBuffer[7] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType;
+				outBuffer[8] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod;
+				outBuffer[9] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour;
+				outBuffer[10] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute;
+				outBuffer[11] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour;
+				outBuffer[12] = ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute;
+				break;
+			case 'J':
+				outBuffer[6] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isEnable;
+				outBuffer[7] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleType;
+				outBuffer[8] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleMethod;
+				outBuffer[9] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour;
+				outBuffer[10] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute;
+				outBuffer[11] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour;
+				outBuffer[12] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute;
+				break;
+			case 'U':
+			case 'E':
+				outBuffer[6] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isEnable;
+				outBuffer[7] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleType;
+				outBuffer[8] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleMethod;
+				outBuffer[9] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour;
+				outBuffer[10] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute;
+				outBuffer[11] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour;
+				outBuffer[12] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute;
+				break;
+			case 'G':
+				outBuffer[6] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isEnable;
+				outBuffer[7] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleType;
+				outBuffer[8] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleMethod;
+				outBuffer[9] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour;
+				outBuffer[10] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute;
+				outBuffer[11] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour;
+				outBuffer[12] = ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute;
+				break;
+		}
 	}
-	
-	/*
-	 * 	TODO:
-	 * 	1. Connector schedule get
-	 */
 }
 
 uint8_t startConnectorCharging(uint8_t gun_index)
@@ -1965,6 +2222,21 @@ void setConnectorSchedule(uint8_t gun_index, uint8_t *inputBuffer)
 					break;
 			}
 		}
+
+		switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-AC_GUN_IDX])
+		{
+			case '1' ... '6':
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable = inputBuffer[10];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType = inputBuffer[11];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod = inputBuffer[12];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = inputBuffer[13];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = inputBuffer[14];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = inputBuffer[15];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = inputBuffer[16];
+
+				scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+				break;
+		}
 	}
 	else if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'D')
 	{
@@ -1987,12 +2259,56 @@ void setConnectorSchedule(uint8_t gun_index, uint8_t *inputBuffer)
 					break;
 			}
 		}
-	}
 
-	/*
-	 * 	TODO:
-	 * 	1. Connector schedule configuration
-	 */
+		switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
+		{
+			case '1' ... '6':
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable = inputBuffer[10];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType = inputBuffer[11];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod = inputBuffer[12];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = inputBuffer[13];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = inputBuffer[14];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = inputBuffer[15];
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = inputBuffer[16];
+
+				scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+				break;
+			case 'J':
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isEnable = inputBuffer[10];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleType = inputBuffer[11];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleMethod = inputBuffer[12];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour = inputBuffer[13];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute = inputBuffer[14];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour = inputBuffer[15];
+				ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute = inputBuffer[16];
+
+				scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule);
+				break;
+			case 'U':
+			case 'E':
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isEnable = inputBuffer[10];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleType = inputBuffer[11];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleMethod = inputBuffer[12];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour = inputBuffer[13];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute = inputBuffer[14];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour = inputBuffer[15];
+				ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute = inputBuffer[16];
+
+				scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule);
+				break;
+			case 'G':
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isEnable = inputBuffer[10];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleType = inputBuffer[11];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleMethod = inputBuffer[12];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour = inputBuffer[13];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute = inputBuffer[14];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour = inputBuffer[15];
+				ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute = inputBuffer[16];
+
+				scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule);
+				break;
+		}
+	}
 }
 
 void getConnectorUser(uint8_t gun_index, uint8_t *outBuffer)
@@ -2096,6 +2412,273 @@ void getConnectorUser(uint8_t gun_index, uint8_t *outBuffer)
 	}
 }
 
+void checkSchedule()
+{
+	uint8_t idxAC = 0;
+	uint8_t idxCCS = 0;
+	uint8_t idxCHAdeMO = 0;
+	uint8_t idxGBT = 0;
+	uint8_t AC_GUN_IDX = 0;
+	time_t CurrentTime;
+	struct tm *tm;
+
+	CurrentTime = time(NULL);
+	tm=localtime(&CurrentTime);
+
+	if((time((time_t*)NULL)%60) == 0)
+	{
+		for(int gun_index=0;gun_index<(AC_QUANTITY+CHAdeMO_QUANTITY+CCS_QUANTITY+GB_QUANTITY);gun_index++)
+		{
+			if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'A')
+			{
+				if(gun_index == 2)
+				{
+					AC_GUN_IDX = 0;
+				}
+				else if(gun_index == 1)
+				{
+					AC_GUN_IDX = 1;
+				}
+				else if(gun_index == 0)
+				{
+					AC_GUN_IDX = 2;
+				}
+
+				for(uint8_t idx=0;idx<AC_GUN_IDX;idx++)
+				{
+					switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-idx])
+					{
+						case '1' ... '6':
+							idxAC++;
+							break;
+					}
+				}
+
+				switch(ShmSysConfigAndInfo->SysConfig.ModelName[9-AC_GUN_IDX])
+				{
+					case '1' ... '6':
+						// Check schedule start
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger start...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isTriggerStart = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+							}
+						}
+
+						// Check schedule stop
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger stop...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isTriggerStop = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+							}
+						}
+						break;
+				}
+			}
+			else if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'D')
+			{
+				for(uint8_t idx=0;idx<gun_index;idx++)
+				{
+					switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+idx])
+					{
+						case '1' ... '6':
+							idxAC++;
+							break;
+						case 'J':
+							idxCHAdeMO++;
+							break;
+						case 'U':
+						case 'E':
+							idxCCS++;
+							break;
+						case 'G':
+							idxGBT++;
+							break;
+					}
+				}
+
+				switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+gun_index])
+				{
+					case '1' ... '6':
+						// AC
+						// Check schedule start
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger start...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isTriggerStart = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.startTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+							}
+						}
+
+						// Check schedule stop
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleMethod) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger stop...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour, ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.isTriggerStop = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule.stopTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.AcChargingData[idxAC].schedule);
+							}
+						}
+
+						break;
+					case 'J':
+						// CHAdeMO
+						// Check schedule start
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger start...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isTriggerStart = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.startTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule);
+							}
+						}
+
+						// Check schedule stop
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleMethod) &&
+						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger stop...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.isTriggerStop = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule.stopTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[idxCHAdeMO].schedule);
+							}
+						}
+
+						break;
+					case 'U':
+					case 'E':
+						// CCS
+						// Check schedule start
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger start...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour, ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isTriggerStart = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.startTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule);
+							}
+						}
+
+						// Check schedule stop
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleMethod) &&
+						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger stop...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour, ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.isTriggerStop = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule.stopTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.CcsChargingData[idxCCS].schedule);
+							}
+						}
+
+						break;
+					case 'G':
+						// GBT
+						// Check schedule start
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger start...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour, ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isTriggerStart = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.startTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.GbChargingData[idxCHAdeMO].schedule);
+							}
+						}
+
+						// Check schedule stop
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isEnable) &&
+						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleMethod) &&
+						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour == tm->tm_hour) &&
+						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute == tm->tm_min))
+						{
+							DEBUG_INFO("Gun-%02d Schedule trigger stop...%02d:%02d\n", gun_index, ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour, ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute);
+							ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.isTriggerStop = ON;
+
+							// Disable schedule time if type is once(0)
+							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.scheduleType == 0)
+							{
+								ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeHour = 0xff;
+								ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule.stopTimeMinute = 0xff;
+								scheduleSaveToDb(localDb, gun_index, &ShmSysConfigAndInfo->SysInfo.GbChargingData[idxGBT].schedule);
+							}
+						}
+
+						break;
+					default:
+						break;
+				}
+			}
+		}
+	}
+}
+
 int tcpSocketServerStart(void)
 {
 	int 				sockFd = 0;
@@ -2590,11 +3173,11 @@ int tcpSocketServerStart(void)
 							outBuffer[0] = 0xff;
 							outBuffer[1] = 0xff;
 							outBuffer[2] = 0x00;
-							outBuffer[3] = 0x06;
+							outBuffer[3] = 0x0a;
 							outBuffer[4] = WIFI_CMD_GET_SCHEDULE;
 							outBuffer[5] = inputBuffer[9];
 							getConnectorSchedule(inputBuffer[9], outBuffer);
-							outBuffer[9] = chksumCal(outBuffer);
+							outBuffer[14] = chksumCal(outBuffer);
 
 							break;
 						case WIFI_CMD_GET_NETWORK_STS:
@@ -3077,8 +3660,21 @@ int tcpSocketServerStart(void)
 								DEBUG_INFO("Schedule enable.\n");
 							else
 								DEBUG_INFO("Schedule disable.\n");
-							DEBUG_INFO("Schedule hour: %d.\n", inputBuffer[11]);
-							DEBUG_INFO("Schedule minute: %d.\n", inputBuffer[12]);
+
+							if(inputBuffer[11])
+								DEBUG_INFO("Schedule type: Daily.\n");
+							else
+								DEBUG_INFO("Schedule type: Once.\n");
+
+							if(inputBuffer[12])
+								DEBUG_INFO("Schedule end method: Specific stop time.\n");
+							else
+								DEBUG_INFO("Schedule end method: Continuous.\n");
+
+							DEBUG_INFO("Schedule start hour: %d.\n", inputBuffer[13]);
+							DEBUG_INFO("Schedule start minute: %d.\n", inputBuffer[14]);
+							DEBUG_INFO("Schedule stop hour: %d.\n", inputBuffer[15]);
+							DEBUG_INFO("Schedule stop minute: %d.\n", inputBuffer[16]);
 
 							setConnectorSchedule(inputBuffer[9], inputBuffer);
 
@@ -3885,11 +4481,11 @@ void proc_killConnection()
 	char cmdBuf[512];
 	
 	// Initialization flags when network is disable mode
-	ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi=1;
-	ShmStatusCodeData->InfoCode.InfoEvents.bits.ApDisconnectViaWiFi=1;
-	ShmSysConfigAndInfo->SysConfig.AthInterface.WifiNetworkConn=0;
-	ShmStatusCodeData->FaultCode.FaultEvents.bits.WiFiModuleBroken=0;
-	ShmStatusCodeData->AlarmCode.AlarmEvents.bits.WiFiModuleCommFail=0;
+	ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi=OFF;
+	ShmStatusCodeData->InfoCode.InfoEvents.bits.ApDisconnectViaWiFi=OFF;
+	ShmSysConfigAndInfo->SysConfig.AthInterface.WifiNetworkConn=OFF;
+	ShmStatusCodeData->FaultCode.FaultEvents.bits.WiFiModuleBroken=OFF;
+	ShmStatusCodeData->AlarmCode.AlarmEvents.bits.WiFiModuleCommFail=OFF;
 	
 	// Stop dhcp client or server
 	sprintf(cmdBuf, "pgrep -f \"udhcpc -i %s\" | xargs kill", Wifi.currentInterface);
@@ -3906,6 +4502,16 @@ void proc_killConnection()
 	sprintf(cmdBuf, "pgrep -f \"hostapd\" | xargs kill");
 	system(cmdBuf);
 	
+#ifdef UBLOX
+	system("ifconfig mlan0 down");
+	system("ifconfig uap0 down");
+#endif
+
+#ifdef MT7601U
+	system("ifconfig wlan0 down");
+#endif
+
+
 	// Clean share memory when network is disable mode
 	memset(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiIpAddress, 0, sizeof ShmSysConfigAndInfo->SysConfig.AthInterface.WifiIpAddress);
 	memset(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSubmaskAddress, 0, sizeof ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSubmaskAddress);
@@ -3938,6 +4544,10 @@ int main(void)
 		DEBUG_ERROR("Puk pin list local db initial fail.\n");
 	}
 
+	// Load schedule from local database
+	for(int gun_index=0;gun_index<(AC_QUANTITY+CHAdeMO_QUANTITY+CCS_QUANTITY+GB_QUANTITY);gun_index++)
+		scheduleLoadFromDb(localDb, gun_index);
+
 	// Wifi login info initial & PUK generate
 	wifi_login_info.loginRole = ROLE_UNKNOWN;
 	memset(&wifi_login_info.loginId[0], 0x00, ARRAY_SIZE(wifi_login_info.loginId));
@@ -3968,6 +4578,19 @@ int main(void)
 		}
 	}
 
+	// Schedule check thread start
+	pid = fork();
+	if(pid == 0)
+	{
+		for(;;)
+		{
+			// Check schedule start/stop event
+			checkSchedule();
+			sleep(1);
+		}
+		return 0;
+	}
+
 	//=============================================
 	// Install WIFI module driver
 	//=============================================

+ 20 - 6
EVSE/Projects/define.h

@@ -343,6 +343,19 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct Schedule
+{
+	unsigned char   isEnable;     						// 0: disable schedule function  1: enable schedule function
+	unsigned char   scheduleType;    					// 0: Once   1: Daily
+	unsigned char   scheduleMethod;    					// 0: Continuous 1: Specificate end time
+	unsigned char   startTimeHour;    					// Schedule start trigger time hour
+	unsigned char   startTimeMinute;   					// Schedule start trigger time minute
+	unsigned char   stopTimeHour;    					// Schedule stop trigger time hour
+	unsigned char   stopTimeMinute;    					// Schedule stop trigger time minute
+	unsigned char   isTriggerStart;    					// 0: disable; 1: enable
+	unsigned char   isTriggerStop;    					// 0: disable; 1: enable
+};
+
 struct SysConfigData
 {
 	/**************System***************/
@@ -456,8 +469,8 @@ struct ChargingInfoData
 	struct timeval		TimeoutTimer;
 	unsigned char 		MaxChargeEnable;
 	unsigned char		IsReadyToCharging;
-	unsigned char		CcsAuthentication;		// 0:EIM, 1:EIM & PnC mixed
-	unsigned char		AcCcsChargingMode;		// 0:BC (PWM) only, 1:BC & PLC mixed
+	unsigned char		CcsAuthentication;				// 0:EIM, 1:EIM & PnC mixed
+	unsigned char		AcCcsChargingMode;				// 0:BC (PWM) only, 1:BC & PLC mixed
 	unsigned short		SampleChargingCur[10];
 
 	/**************Alston for AC***************/
@@ -472,16 +485,17 @@ struct ChargingInfoData
 	unsigned char 		ConnectorWarningCode[7];
 	unsigned char 		ConnectorAlarmCode[7];
 	unsigned char 		EvConnAlarmCode[7];
-	float 				ChargingProfileCurrent;	//0~6553.5 amp
-	float 				ChargingProfilePower;	//0~6553.5 kW
-	float 				PresentChargingVoltageL2;	//0~6553.5 volt
-	float 				PresentChargingVoltageL3;	//0~6553.5 volt
+	float 				ChargingProfileCurrent;			//0~6553.5 amp
+	float 				ChargingProfilePower;			//0~6553.5 kW
+	float 				PresentChargingVoltageL2;		//0~6553.5 volt
+	float 				PresentChargingVoltageL3;		//0~6553.5 volt
 	float 				PresentChargingCurrentL2;		//0~6553.5 amp	
 	float 				PresentChargingCurrentL3;		//0~6553.5 amp
 	char 				RemoteStartFlag;
 	unsigned char 		MaxChargingToAverPassFlag;
 	unsigned char		EVCCID[18];						//the MAC address of the EVCC in Hex
 	unsigned char 		isRemoteStart;
+	struct Schedule		schedule;						// Schedule
 };
 
 struct SysInfoData