Browse Source

2020.03.12 / Folus Wen

Actions:
1. Synchronize apps from AW-Regular to Noodoe

Files:
1. As follow commit history

Image version: B0.22.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 5 năm trước cách đây
mục cha
commit
1cc60b390b

+ 1 - 1
EVSE/Projects/Noodoe/Apps/Module_FactoryConfig.c

@@ -275,7 +275,7 @@ int main(int argc, char *argv[])
 	SysConfig.AthInterface.WifiDhcpServer = 0;	// 0: Enable	1: Disable
 	SysConfig.AthInterface.WifiDhcpClient = 0;	// 0: Enable	1: Disable
 
-	strcpy((char*)SysConfig.TelecomInterface.TelcomApn, "internet");
+	strcpy((char*)SysConfig.TelecomInterface.TelcomApn, "");
 	SysConfig.TelecomInterface.TelcomSimStatus = 0;	// SIM card status
 	SysConfig.TelecomInterface.TelcomModemMode = 0;	//0: No services	1: CDMA		2: GSM/GPRS	3: WCDMA	4: GSM/WCDMA	5: TD_SCDMA		6: Unknown
 

+ 206 - 13
EVSE/Projects/Noodoe/Apps/Module_InternalComm.c

@@ -1441,7 +1441,132 @@ unsigned char Config_AC_MaxCurrent_And_CpPwmDuty(unsigned char fd, unsigned char
 			result = PASS;
 		}
 	}
-		return result;
+
+	return result;
+}
+
+unsigned char Config_AC_Set_Breathe_Led_Timing(unsigned char fd, unsigned char targetAddr,Set_Breathe_Led_Timing*Set_Buf)
+{
+	unsigned char result = FAIL;
+	unsigned char tx[19];
+	unsigned char rx[512];
+	unsigned char chksum = 0x00;
+
+	tx[0] = 0xaa;
+	tx[1] = 0x00;
+	tx[2] = targetAddr;
+	tx[3] = CMD_CONFIG_MCU_SET_BREATHE_LED_TIMING;
+	tx[4] = 0x0C;
+	tx[5] = 0x00;
+
+	// Increase LED_ACTION_CONNECTED
+	tx[6] = (Set_Buf->set_Led_Action_Connected_Fade_In & 0xff);
+	tx[7] = (Set_Buf->set_Led_Action_Connected_Fade_In >> 8);
+
+	// Decrease LED_ACTION_CONNECTED
+	tx[8] = (Set_Buf->set_Led_Action_Connected_Fade_Out & 0xff);
+	tx[9] = (Set_Buf->set_Led_Action_Connected_Fade_Out >> 8);
+
+	// Increase LED_ACTION_AUTHED
+	tx[10] = (Set_Buf->set_Led_Action_Authed_Fade_In & 0xff);
+	tx[11] = (Set_Buf->set_Led_Action_Authed_Fade_In >> 8);
+
+	// Decrease LED_ACTION_AUTHED
+	tx[12] = (Set_Buf->set_Led_Action_Authed_Fade_Out & 0xff);
+	tx[13] = (Set_Buf->set_Led_Action_Authed_Fade_Out >> 8);
+
+	// Increase_LED_ACTION_CHARGING
+	tx[14] = (Set_Buf->Set_Led_Action_Chaging_Fade_In & 0xff);
+	tx[15] = (Set_Buf->Set_Led_Action_Chaging_Fade_In >> 8);
+
+	// Decrease_LED_ACTION_CHARGING
+	tx[16] = (Set_Buf->set_Led_Action_Chaging_Fade_Out & 0xff);
+	tx[17] = (Set_Buf->set_Led_Action_Chaging_Fade_Out >> 8);
+
+	for(int idx=0;idx<(tx[4] | tx[5]<<8);idx++)
+		chksum ^= tx[6+idx];
+	tx[18] = chksum;
+
+	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+	if(len > 6)
+	{
+		if(len < 6+(rx[4] | rx[5]<<8))
+			return result;
+
+		chksum = 0x00;
+		for(int idx=0;idx<(rx[4] | rx[5]<<8);idx++)
+		{
+			chksum ^= rx[6+idx];
+		}
+
+		if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+			(rx[2] == tx[1]) &&
+			(rx[1] == tx[2]) &&
+			(rx[3] == tx[3]) &&
+			(rx[6] == 0x01))
+		{
+			result = PASS;
+		}
+	}
+
+	return result;
+}
+
+unsigned char Config_AC_Set_Led_Brightness(unsigned char fd, unsigned char targetAddr,Set_Led_Brightness*Set_Buf)
+{
+	unsigned char result = FAIL;
+	unsigned char tx[19];
+	unsigned char rx[512];
+	unsigned char chksum = 0x00;
+
+	tx[0] = 0xaa;
+	tx[1] = 0x00;
+	tx[2] = targetAddr;
+	tx[3] = CMD_CONFIG_MCU_SET_LED_BRIGHTNESS;
+	tx[4] = 0x0C;
+	tx[5] = 0x00;
+	tx[6] = Set_Buf-> sector_1;			// 0~1 AM and 1~2 AM
+	tx[7] = Set_Buf-> sector_2;			// 2~3 AM and 3~4 AM
+	tx[8] = Set_Buf-> sector_3;			// 4~5 AM and 5~6 AM
+	tx[9] = Set_Buf-> sector_4;			// 6~7 AM and 7~8 AM
+	tx[10] = Set_Buf-> sector_5;		// 8~9 AM and 9~10 AM
+	tx[11] = Set_Buf-> sector_6;		// 10~11 AM and 11~12 AM
+	tx[12] = Set_Buf-> sector_7;		// 12~13 PM and 13~14 PM
+	tx[13] = Set_Buf-> sector_8;		// 14~15 PM and 15~16 PM
+	tx[14] = Set_Buf-> sector_9;		// 16~17 PM and 17~18 PM
+	tx[15] = Set_Buf-> sector_10;		// 18~19 PM and 19~20 PM
+	tx[16] = Set_Buf-> sector_11;		// 20~21 PM and 21~22 PM
+	tx[17] = Set_Buf-> sector_12;		// 22~23 PM and 23~24 PM
+
+	for(int idx=0;idx<(tx[4] | tx[5]<<8);idx++)
+			chksum ^= tx[6+idx];
+	tx[18] = chksum;
+
+	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+	if(len > 6)
+	{
+		if(len < 6+(rx[4] | rx[5]<<8))
+			return result;
+
+		chksum = 0x00;
+		for(int idx=0;idx<(rx[4] | rx[5]<<8);idx++)
+		{
+			chksum ^= rx[6+idx];
+		}
+
+		if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+			(rx[2] == tx[1]) &&
+			(rx[1] == tx[2]) &&
+			(rx[3] == tx[3]) &&
+			(rx[6] == 0x01))
+		{
+			result = PASS;
+		}
+	}
+
+	return result;
 }
 
 unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned int crc32)
@@ -2233,14 +2358,44 @@ int main(void)
 						}
 						break;
 					case 17:
-						//DEBUG_INFO("==================================================\r\n");
-						//DEBUG_INFO("======== Normal priority polling : Case 17 =======\r\n");
-						//DEBUG_INFO("==================================================\r\n");
+						//===============================
+						// Config set breathe led timing
+						//===============================
+						if(ShmCharger->gun_info[gun_index].isSetBreatheLedTiming == ON)
+						{
+							if(Config_AC_Set_Breathe_Led_Timing(Uart1Fd, (gun_index>0?ADDR_AC_PRIMARY_2:ADDR_AC_PRIMARY_1), &ShmCharger->gun_info[gun_index].setBreatheLedTiming))
+							{
+								failCount[gun_index] = 0;
+							}
+							else
+							{
+								DEBUG_WARN("MCU-%d set breathe led timing fail...%d\r\n", gun_index, failCount[gun_index]);
+								if(failCount[gun_index]<1000)
+								{
+									failCount[gun_index]++;
+								}
+							}
+						}
 						break;
 					case 19:
-						//DEBUG_INFO("==================================================\r\n");
-						//DEBUG_INFO("======== Normal priority polling : Case 19 =======\r\n");
-						//DEBUG_INFO("==================================================\r\n");
+						//===============================
+						// Config set led brightness
+						//===============================
+						if(ShmCharger->gun_info[gun_index].isSetLedBrightness == ON)
+						{
+							if(Config_AC_Set_Led_Brightness(Uart1Fd, (gun_index>0?ADDR_AC_PRIMARY_2:ADDR_AC_PRIMARY_1), &ShmCharger->gun_info[gun_index].setLedBrightness))
+							{
+								failCount[gun_index] = 0;
+							}
+							else
+							{
+								DEBUG_WARN("MCU-%d set led brightness fail...%d\r\n", gun_index, failCount[gun_index]);
+								if(failCount[gun_index]<1000)
+								{
+									failCount[gun_index]++;
+								}
+							}
+						}
 						break;
 					case 21:
 						//===============================
@@ -2346,28 +2501,28 @@ int main(void)
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("MCU-%d get output current : %f\r\n", gun_index, (float)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]);
 					}
-					else if (stepIndex == 5)
+					else if(stepIndex == 5)
 					{
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("======== Normal priority polling : Case 5 ========\r\n");
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("MCU-%d get gun plugin times : %ld\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].gunPluginTimes.GunPluginTimes);
 					}
-					else if (stepIndex == 7)
+					else if(stepIndex == 7)
 					{
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("======== Normal priority polling : Case 7 ========\r\n");
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("MCU-%d get temperature : %d\r\n", gun_index, ShmCharger->gun_info[gun_index].temperature.point[0]);
 					}
-					else if (stepIndex == 9)
+					else if(stepIndex == 9)
 					{
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("======== Normal priority polling : Case 9 ========\r\n");
 						DEBUG_INFO("==================================================\r\n");
-						DEBUG_INFO("MCU-%d cp pwn duty : %d\r\n",gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current);
+						DEBUG_INFO("MCU-%d set cp pwn duty : %d\r\n",gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current);
 					}
-					else if (stepIndex == 11)
+					else if(stepIndex == 11)
 					{
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("======== Normal priority polling : Case 11 =======\r\n");
@@ -2395,13 +2550,51 @@ int main(void)
 																										ShmCharger->gun_info[gun_index].rtc.sec);
 						}
 					}
-					else if (stepIndex == 13)
+					else if(stepIndex == 13)
 					{
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("======== Normal priority polling : Case 13 =======\r\n");
 						DEBUG_INFO("==================================================\r\n");
 						DEBUG_INFO("MCU-%d get power consumption : %f kWh\r\n",gun_index, ((float)ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100));
 					}
+					else if(stepIndex == 17)
+					{
+						if(ShmCharger->gun_info[gun_index].isSetBreatheLedTiming == ON)
+						{
+							DEBUG_INFO("==================================================\r\n");
+							DEBUG_INFO("======== Normal priority polling : Case 17 =======\r\n");
+							DEBUG_INFO("==================================================\r\n");
+							DEBUG_INFO("MCU-%d set breathe led timing : Authed Fade in [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.set_Led_Action_Authed_Fade_In);
+							DEBUG_INFO("MCU-%d set breathe led timing : Authed Fade out [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.set_Led_Action_Authed_Fade_Out);
+							DEBUG_INFO("MCU-%d set breathe led timing : Charging Fade in [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.Set_Led_Action_Chaging_Fade_In);
+							DEBUG_INFO("MCU-%d set breathe led timing : Charging Fade out [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.set_Led_Action_Chaging_Fade_Out);
+							DEBUG_INFO("MCU-%d set breathe led timing : Connected Fade in [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.set_Led_Action_Connected_Fade_In);
+							DEBUG_INFO("MCU-%d set breathe led timing : Connected Fade out [%ld].\r\n", gun_index, (long)ShmCharger->gun_info[gun_index].setBreatheLedTiming.set_Led_Action_Connected_Fade_Out);
+						}
+					}
+					else if(stepIndex == 19)
+					{
+						if(ShmCharger->gun_info[gun_index].isSetLedBrightness == ON)
+						{
+							DEBUG_INFO("==================================================\r\n");
+							DEBUG_INFO("======== Normal priority polling : Case 19 =======\r\n");
+							DEBUG_INFO("==================================================\r\n");
+							DEBUG_INFO("MCU-%d set led brightness Sector 01 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_1);
+							DEBUG_INFO("MCU-%d set led brightness Sector 02 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_2);
+							DEBUG_INFO("MCU-%d set led brightness Sector 03 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_3);
+							DEBUG_INFO("MCU-%d set led brightness Sector 04 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_4);
+							DEBUG_INFO("MCU-%d set led brightness Sector 05 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_5);
+							DEBUG_INFO("MCU-%d set led brightness Sector 06 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_6);
+							DEBUG_INFO("MCU-%d set led brightness Sector 07 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_7);
+							DEBUG_INFO("MCU-%d set led brightness Sector 08 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_8);
+							DEBUG_INFO("MCU-%d set led brightness Sector 09 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_9);
+							DEBUG_INFO("MCU-%d set led brightness Sector 10 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_10);
+							DEBUG_INFO("MCU-%d set led brightness Sector 11 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_11);
+							DEBUG_INFO("MCU-%d set led brightness Sector 12 : [%x].\r\n", gun_index, ShmCharger->gun_info[gun_index].setLedBrightness.sector_12);
+						}
+					}
+					else
+					{}
 
 					usleep(100000);
 				}

+ 3 - 1
EVSE/Projects/Noodoe/Apps/Module_InternalComm.h

@@ -1,7 +1,7 @@
 /*
  * Module_InternalComm.h
  *
- *  Created on: 2020¦~01¤ë15¤é
+ *  Created on: 2020年01�15日
  *      Author: USER
  */
 
@@ -46,6 +46,8 @@ enum MESSAGE_COMMAND
 	CMD_CONFIG_CURRENT_LINIT = 0x89,
 	CMD_CONFIG_MCU_MODE = 0x8A,
 	CMD_CONFIG_MCU_RESET_REQUEST = 0x8C,
+	CMD_CONFIG_MCU_SET_BREATHE_LED_TIMING = 0x8D,
+	CMD_CONFIG_MCU_SET_LED_BRIGHTNESS = 0x8E,
 
 	CMD_UPDATE_START = 0xe0,
 	CMD_UPDATE_ABOARD = 0xe1,

+ 222 - 79
EVSE/Projects/Noodoe/Apps/main.c

@@ -45,9 +45,6 @@ void split(char **arr, char *str, const char *del);
 
 int isReachableInternet();
 int InitRfidPort(void);
-int GetAlarmValue(void);
-int GetInfoValue(void);
-int GetFaultValue(void);
 int GetCardSerialNumber();
 void setLedMotion(unsigned char gun_index,unsigned char led_mode);
 void setRelay(unsigned char gun_index,unsigned char isOn);
@@ -774,6 +771,7 @@ void InitEthernet()
 		ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);
 		system(tmpbuf);
 		system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up");
+		system("ifconfig lo up");
 	}
 
 	if(isInterfaceUp("eth1")==PASS)
@@ -1063,7 +1061,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.20.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.22.00.0000.00");
 
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
@@ -1210,21 +1208,32 @@ int upgrade_check()
 								break;
 						}
 					}
+					else
+					{
+						result = FAIL;
+						DEBUG_ERROR("Model name and Firmware type error.\r\n");
+					}
 
 					free(ptr);
 				}
 				else
 				{
-					// File open error
+					result = FAIL;
 					DEBUG_ERROR("New firmware open error.\r\n");
 				}
 			}
+			else
+			{
+				result = FAIL;
+				DEBUG_ERROR("File name error.\r\n");
+			}
 		}
 		closedir (dir);
 	}
 	else
 	{
-	  DEBUG_ERROR("/mnt does not valid.\r\n");
+		result = FAIL;
+		DEBUG_ERROR("/mnt does not valid.\r\n");
 	}
 
 	return result;
@@ -1319,59 +1328,6 @@ int GetCardSerialNumber()
 	return isSuccess;
 }
 
-//===============================================
-// Alarm value check
-//===============================================
-int GetAlarmValue()
-{
-	int result = PASS;
-
-	if( (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[0] > 0) || (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[1] > 0) || (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[2] > 0) ||
-		(ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[3] > 0) || (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[4] > 0) || (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[5] > 0) ||
-		(ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[6] > 0) || (ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[7] > 0))
-	{
-		result = FAIL;
-	}
-
-	return result;
-}
-
-//===============================================
-// Info value check
-//===============================================
-int GetInfoValue()
-{
-	int result = PASS;
-
-	if( (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[0] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[1] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[2] > 0) ||
-		(ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[3] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[4] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[5] > 0) ||
-		(ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[6] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[7] > 0) || (ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[8] > 0) ||
-		(ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[9] > 0))
-	{
-		result = FAIL;
-	}
-
-	return result;
-}
-
-//===============================================
-// Fault value check
-//===============================================
-int GetFaultValue()
-{
-	int result = PASS;
-
-	if( (ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[0] > 0) ||
-		(ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[1] > 0) ||
-		(ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[2] > 0) ||
-		(ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[3] > 0))
-	{
-		result = FAIL;
-	}
-
-	return result;
-}
-
 //===============================================
 // Set led motion
 //===============================================
@@ -1582,6 +1538,113 @@ int isReservationExpired(unsigned char gun_index)
 	return result;
 }
 
+//===============================================
+// Check charging profile related date routine
+//===============================================
+int isProfileValid(uint8_t gun_index)
+{
+	int result = NO;
+	struct tm tmFrom, tmTo;
+	struct timeb tbFrom, tbTo;
+
+	if((sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom, "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) &&
+	   (sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo, "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6))
+	{
+		tmFrom.tm_year -= 1900;
+		tmFrom.tm_mon -= 1;
+		tbFrom.time = mktime(&tmFrom);
+
+		tmTo.tm_year -= 1900;
+		tmTo.tm_mon -= 1;
+		tbTo.time = mktime(&tmTo);
+
+		DEBUG_INFO("Valid from compare Now: %d\r\n", DiffTimebWithNow(tbFrom));
+		DEBUG_INFO("Valid to compare Now: %d\r\n", DiffTimebWithNow(tbTo));
+		if((DiffTimebWithNow(tbFrom)>=0) && (DiffTimebWithNow(tbTo)<=0))
+		{
+			result = YES;
+		}
+	}
+	else
+	{
+		DEBUG_WARN("ValidFrom or ValidTo date parsing error.\r\n");
+	}
+
+	return result;
+}
+
+int getScheduleStart(int gun_index)
+{
+	int result = -1;
+	struct tm tmScheduleStart;;
+	struct timeb tbScheduleStart;
+
+
+	if((sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6))
+	{
+		tmScheduleStart.tm_year -= 1900;
+		tmScheduleStart.tm_mon -= 1;
+		tbScheduleStart.time = mktime(&tmScheduleStart);
+
+		result = DiffTimebWithNow(tbScheduleStart)/1000;
+
+		DEBUG_INFO("Schedule start compare Now(seconds): %d\r\n", result);
+	}
+	else
+	{
+		DEBUG_WARN("Schedule start date parsing error.\r\n");
+	}
+
+
+	return result;
+}
+
+int getStartSinceToday()
+{
+	int result = -1;
+	time_t t;
+	struct tm *tmStartToday;
+	struct timeb tbStartToday;
+
+	t=time(NULL);
+	tmStartToday=localtime(&t);
+
+	tmStartToday->tm_hour = 0;
+	tmStartToday->tm_min = 0;
+	tmStartToday->tm_sec = 0;
+
+	tbStartToday.time = mktime(tmStartToday);
+
+	result = DiffTimebWithNow(tbStartToday)/1000;
+	DEBUG_INFO("Start today compare Now(seconds): %d\r\n", result);
+
+	return result;
+}
+
+int getStartSinceWeek()
+{
+	int result = -1;
+	time_t t;
+	struct tm *tmStartWeek;
+	struct timeb tbStartWeek;
+
+	t=time(NULL);
+	tmStartWeek=localtime(&t);
+
+	tmStartWeek->tm_wday = 0;
+	tmStartWeek->tm_hour = 0;
+	tmStartWeek->tm_min = 0;
+	tmStartWeek->tm_sec = 0;
+
+	tbStartWeek.time = mktime(tmStartWeek);
+
+	result = DiffTimebWithNow(tbStartWeek)/1000;
+
+	DEBUG_INFO("Start week compare Now(seconds): %d\r\n", result);
+
+	return result;
+}
+
 //===============================================
 // Valid from local white list
 //===============================================
@@ -1729,7 +1792,6 @@ void checkConnectionTimeout()
 			ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING;
 			//DEBUG_INFO("Handshaking timeout specification follow by OCPP Configuration : Fail. Table is blank...\r\n.");
 		}
-
 		//DEBUG_INFO("Present timeout spec : %d \r\n", ShmCharger->timeoutSpec.Present_Timeout_Spec);
 	}
 }
@@ -1764,6 +1826,8 @@ int main(void)
 		ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch = 0xff;
 		ShmCharger->gun_info[gun_index].mcuResetRequest.isMcuResetRequest = ON;
 		ShmCharger->gun_info[gun_index].isInitialPass = NO;
+		ShmCharger->gun_info[gun_index].isSetBreatheLedTiming = OFF;
+		ShmCharger->gun_info[gun_index].isSetLedBrightness = OFF;
 	}
 
 	// Main loop
@@ -1936,6 +2000,16 @@ int main(void)
 				}
 			}
 
+			// Charging profile preparation
+			if(!ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf)
+			{
+				ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq = ON;
+			}
+			else
+			{
+				ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf = OFF;
+			}
+
 			// Connector process
 			switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)
 			{
@@ -2277,11 +2351,92 @@ int main(void)
 						if(ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf == ON)
 							ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf = OFF;
 
-						/*
-						 * TODO:
-						 * 	1. Query target current from charging profile
-						 */
-						// Checking charging profile target current
+						// Checking profile id > 0 and current time is between charging profile validFrom & validTo
+						if((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId>0) &&
+						   (((strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom)>0) && (strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo)>0)) ? isProfileValid(gun_index) : ON))
+						{
+							DEBUG_INFO("Profile ID found: %d\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId);
+							DEBUG_INFO("Valid from: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom);
+							DEBUG_INFO("Valid to: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo);
+							DEBUG_INFO("Start schedule: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule);
+							DEBUG_INFO("Profile kind: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind);
+							DEBUG_INFO("RecurrencyKind: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].RecurrencyKind);
+							DEBUG_INFO("Profile purpose: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose);
+							DEBUG_INFO("Transaction ID: %d\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId);
+							DEBUG_INFO("ChargingRateUnit: %s\r\n", ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit);
+
+							// Checking profile kind
+							if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Absolute") == PASS))
+							{
+								// Absolute profile
+								if(((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId == ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId)) ||
+									(mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == FAIL))
+								{
+									// Checking limitation
+									for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
+									{
+										if((getScheduleStart(gun_index) > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
+										   (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 0)) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod != 0)))
+										{
+											ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/220:ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
+											DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
+										}
+									}
+								}
+							}
+							else if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Relative") == PASS))
+							{
+								// Relative profile
+								if(((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId == ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId)) ||
+									(mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == FAIL))
+								{
+									// Checking limitation
+									for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
+									{
+										if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
+										   (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 0)) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod != 0)))
+										{
+											ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/220:ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
+											DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
+										}
+									}
+								}
+							}
+							else
+							{
+								// Recurring profile
+								if(((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId == ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId)) ||
+									(mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == FAIL))
+								{
+									if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].RecurrencyKind, "Daily") == PASS))
+									{
+										// Checking limitation
+										for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
+										{
+											if((getStartSinceToday() > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
+											   (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 0)) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod != 0)))
+											{
+												ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/220:ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
+												DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
+											}
+										}
+									}
+									else
+									{
+										// Checking limitation
+										for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
+										{
+											if((getStartSinceWeek() > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
+											   (((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod == 0) && (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit != 0)) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod != 0)))
+											{
+												ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/220:ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
+												DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\r\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
+											}
+										}
+									}
+								}
+							}
+						}
 
 						// Determine max charging current to MCU
 						if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0)
@@ -2562,13 +2717,7 @@ int main(void)
 					break;
 				case SYS_MODE_FAULT:
 					if(isModeChange(gun_index))
-					{
-						/*
-						 * TODO:
-						 * 1. LED control depend on relay status
-						 * 2. Alarm latch & release logic
-						 */
-					}
+					{}
 
 					break;
 				case SYS_MODE_MAINTAIN:
@@ -2683,13 +2832,7 @@ int main(void)
 					break;
 				case SYS_MODE_BOOKING:
 					if(isModeChange(gun_index))
-					{
-						/*
-						 * TODO:
-						 * 1. LED control depend on relay status
-						 * 2. Check booking start is on time?
-						 */
-					}
+					{}
 					break;
 				case SYS_MODE_DEBUG:
 					if(isModeChange(gun_index))

+ 30 - 0
EVSE/Projects/Noodoe/Apps/main.h

@@ -370,6 +370,32 @@ typedef struct TIMEOUT_SPEC
 	int Present_Timeout_Spec;
 }Timeout_Spec;
 
+typedef struct SET_BREATHE_LED_TIMING
+{
+	uint16_t set_Led_Action_Connected_Fade_In;
+	uint16_t set_Led_Action_Connected_Fade_Out;
+	uint16_t set_Led_Action_Authed_Fade_In;
+	uint16_t set_Led_Action_Authed_Fade_Out;
+	uint16_t Set_Led_Action_Chaging_Fade_In;
+	uint16_t set_Led_Action_Chaging_Fade_Out;
+}Set_Breathe_Led_Timing;
+
+typedef struct SET_LED_BRIGHTNESS
+{
+	uint8_t sector_1;	// 0~1 AM and 1~2 AM
+	uint8_t sector_2;	// 2~3 AM and 3~4 AM
+	uint8_t sector_3;	// 4~5 AM and 5~6 AM
+	uint8_t sector_4;	// 6~7 AM and 7~8 AM
+	uint8_t sector_5;	// 8~9 AM and 9~10 AM
+	uint8_t sector_6;	// 10~11 AM and 11~12 AM
+	uint8_t sector_7;	// 12~13 PM and 13~14 PM
+	uint8_t sector_8;	// 14~15 PM and 15~16 PM
+	uint8_t sector_9;	// 16~17 PM and 17~18 PM
+	uint8_t sector_10;	// 18~19 PM and 19~20 PM
+	uint8_t sector_11;	// 20~21 PM and 21~22 PM
+	uint8_t sector_12;	// 22~23 PM and 23~24 PM
+}Set_Led_Brightness;
+
 typedef struct GUN_INFO
 {
 	Ver 											ver;
@@ -391,11 +417,15 @@ typedef struct GUN_INFO
 	Pilot_Voltage									PilotVoltage;
 	Gun_Plugin_Times								gunPluginTimes;
 	Mcu_Reset_Request								mcuResetRequest;
+	Set_Breathe_Led_Timing							setBreatheLedTiming;
+	Set_Led_Brightness								setLedBrightness;
 	uint16_t										targetCurrent;
 	uint8_t											isAuthPassEnd:1;
 	uint8_t											rfidReq:1;
 	uint8_t											isGunPlugged:1;
 	uint8_t											isInitialPass:1;
+	uint8_t											isSetBreatheLedTiming:1;
+	uint8_t											isSetLedBrightness:1;
 }Gun_Info;
 
 struct Charger