Browse Source

[Improve][AW-CCS / AW-Regular][Module_AlarmDetect]

2021.09.14 / Folus Wen

Actions:
1. Module_AlarmDetect implement OCPP 2.0.1 nofification logic.

Files:
1. As follow commit history

Image version: D0.55.XX.XXXX.P0 (AW-CCS)
               V0.69.XX.XXXX.P0 (AW-Regular)
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 3 years ago
parent
commit
3b6612ebd6

+ 583 - 293
EVSE/Projects/AW-CCS/Apps/Module_AlarmDetect.c

@@ -73,7 +73,7 @@ struct StatusCodeData 			*ShmStatusCodeData;
 struct OCPP16Data				*ShmOCPP16Data;
 struct OCPP20Data				*ShmOCPP20Data;
 struct Charger					*ShmCharger;
-
+unsigned long					previousAlarmCode[AC_QUANTITY];
 
 int StoreLogMsg(const char *fmt, ...)
 {
@@ -1037,7 +1037,7 @@ int main(void)
 					(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE) ||
 					(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE))
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverVoltage");
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == ON)
 						sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012200");
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == ON)
@@ -1050,7 +1050,7 @@ int main(void)
 						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE) ||
 						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE))
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "UnderVoltage");
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == ON)
 						sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012203");
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == ON)
@@ -1063,7 +1063,7 @@ int main(void)
 						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) ||
 						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT))
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverCurrentFailure");
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON)
 						sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012216");
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL2 == ON)
@@ -1074,62 +1074,71 @@ int main(void)
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "HighTemperature");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012223");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "GroundFailure");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012256");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "023703");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "CpError");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012233");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "ACLeakage");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012233");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "DCLeakage");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012257");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "McuTestFail");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "HandshakeTimeout");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "HandshakeTimeout");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012251");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "EmergencyStop");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011009");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RelayWelding");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011004");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "LeakageModuleFail");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011034");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "ShutterFault");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
 				{
-					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "ConnectorLockFailure");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011027");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
@@ -1142,6 +1151,7 @@ int main(void)
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputDrop == ON)
 						sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012214");
 
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "PowerDrop");
 				}
 				else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT) ||
 						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT) ||
@@ -1155,21 +1165,25 @@ int main(void)
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShortL3 == ON)
 						sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012302");
 
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "CircuitShort");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011036");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RotatorySwitchFault");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011010");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RelayDriveFault");
 				}
 				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012305");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "MeterCommunicationTimeout");
 				}
 				else
 				{
@@ -1179,421 +1193,697 @@ int main(void)
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 			{
-				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_VOLTAGE) ||
-					(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE) ||
-					(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE))
+				uint8_t idxEvent = 0;
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L1_OVER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012200");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L1 input OVP");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012201");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L2 input OVP");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012202");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L3 input OVP");
-					}
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012200");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input OVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Voltage");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L1_OVER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L1_OVER_VOLTAGE;
 				}
-				else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_UNDER_VOLTAGE) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE))
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L2_OVER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
 
-					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012203");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L1 input UVP");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012204");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L2 input UVP");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012205");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L3 input UVP");
-					}
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012201");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L2 input OVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Voltage");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L2_OVER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L2_OVER_VOLTAGE;
 				}
-				else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT))
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L3_OVER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012216");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System AC output OCP L1");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL2 == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012299");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System AC output OCP L2");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL3 == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012300");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System AC output OCP L3");
-					}
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012202");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L3 input OVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Current");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L3_OVER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L3_OVER_VOLTAGE;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_UNDER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L1_UNDER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_UNDER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_UNDER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012223");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System ambient/inlet OTP");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012203");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input UVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Temperature");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_UNDER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L1_UNDER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L1_UNDER_VOLTAGE;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L2_UNDER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012256");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "AC Ground Fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012204");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L2 input UVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Ground(PE)");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_UNDER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L2_UNDER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L2_UNDER_VOLTAGE;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_L3_UNDER_VOLTAGE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "023703");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "pilot fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012205");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L3 input UVP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Control pilot");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_UNDER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_L3_UNDER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L3_UNDER_VOLTAGE;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) != (previousAlarmCode[gun_index] & ALARM_L1_OVER_CURRENT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012233");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "RCD/CCID trip");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012216");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System AC output OCP L1");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "CCID");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT)
+						previousAlarmCode[gun_index] |= ALARM_L1_OVER_CURRENT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L1_OVER_CURRENT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) != (previousAlarmCode[gun_index] & ALARM_L2_OVER_CURRENT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012233");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "RCD/CCID trip");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012299");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System AC output OCP L2");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "CCID");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT)
+						previousAlarmCode[gun_index] |= ALARM_L2_OVER_CURRENT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L2_OVER_CURRENT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT) != (previousAlarmCode[gun_index] & ALARM_L3_OVER_CURRENT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012257");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "MCU self-test Fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012300");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System AC output OCP L3");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "MCU");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT)
+						previousAlarmCode[gun_index] |= ALARM_L3_OVER_CURRENT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L3_OVER_CURRENT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE) != (previousAlarmCode[gun_index] & ALARM_OVER_TEMPERATURE))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "HandshakeTimeout");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "HandshakeTimeout");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012223");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System ambient/inlet OTP");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Temperature");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Operation");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
+						previousAlarmCode[gun_index] |= ALARM_OVER_TEMPERATURE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_OVER_TEMPERATURE;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL) != (previousAlarmCode[gun_index] & ALARM_GROUND_FAIL))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012251");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Emergency stop");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012256");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC Ground Fault");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Ground(PE)");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Button");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
+						previousAlarmCode[gun_index] |= ALARM_GROUND_FAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_GROUND_FAIL;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR) != (previousAlarmCode[gun_index] & ALARM_CP_ERROR))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011009");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "AC output relay welding");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "023703");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "pilot fault");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Control pilot");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Relay");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
+						previousAlarmCode[gun_index] |= ALARM_CP_ERROR;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CP_ERROR;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC) != (previousAlarmCode[gun_index] & ALARM_CURRENT_LEAK_AC))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011004");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "RCD/CCID self-test fail");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012233");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID trip");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "CCID");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
+						previousAlarmCode[gun_index] |= ALARM_CURRENT_LEAK_AC;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CURRENT_LEAK_AC;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC) != (previousAlarmCode[gun_index] & ALARM_CURRENT_LEAK_DC))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011034");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Shutter fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012233");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID trip");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Shutter");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
+						previousAlarmCode[gun_index] |= ALARM_CURRENT_LEAK_DC;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CURRENT_LEAK_DC;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL) != (previousAlarmCode[gun_index] & ALARM_MCU_TESTFAIL))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011027");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "AC connector lock fail");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012257");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "MCU self-test Fault");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "MCU");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Locker");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
+						previousAlarmCode[gun_index] |= ALARM_MCU_TESTFAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_MCU_TESTFAIL;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT) != (previousAlarmCode[gun_index] & ALARM_HANDSHAKE_TIMEOUT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "HandshakeTimeout");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "HandshakeTimeout");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Operation");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
+						previousAlarmCode[gun_index] |= ALARM_HANDSHAKE_TIMEOUT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_HANDSHAKE_TIMEOUT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) != (previousAlarmCode[gun_index] & ALARM_EMERGENCY_STOP))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012251");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Emergency stop");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Button");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
+						previousAlarmCode[gun_index] |= ALARM_EMERGENCY_STOP;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_EMERGENCY_STOP;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING) != (previousAlarmCode[gun_index] & ALARM_RELAY_WELDING))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011009");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC output relay welding");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Relay");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
+						previousAlarmCode[gun_index] |= ALARM_RELAY_WELDING;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_RELAY_WELDING;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL) != (previousAlarmCode[gun_index] & ALARM_LEAK_MODULE_FAIL))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011004");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID self-test fail");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
+						previousAlarmCode[gun_index] |= ALARM_LEAK_MODULE_FAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_LEAK_MODULE_FAIL;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT) != (previousAlarmCode[gun_index] & ALARM_SHUTTER_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011034");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Shutter fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Shutter");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_SHUTTER_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_SHUTTER_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT) != (previousAlarmCode[gun_index] & ALARM_LOCKER_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011027");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC connector lock fail");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Locker");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_LOCKER_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_LOCKER_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP) != (previousAlarmCode[gun_index] & ALARM_POWER_DROP))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop == ON)
 					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012212");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L1 input drop");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012212");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input drop");
 					}
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputDrop == ON)
 					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012213");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L2 input drop");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012213");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L2 input drop");
 					}
 					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputDrop == ON)
 					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012214");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "System L3 input drop");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012214");
+						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L3 input drop");
 					}
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Voltage");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
+						previousAlarmCode[gun_index] |= ALARM_POWER_DROP;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_POWER_DROP;
 				}
-				else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT) ||
-						(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_CIRCUIT_SHORT))
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT) != (previousAlarmCode[gun_index] & ALARM_L1_CIRCUIT_SHORT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012262");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Circuit Short L1");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShortL2 == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012301");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Circuit Short L2");
-					}
-					else if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShortL3 == ON)
-					{
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012302");
-						sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Circuit Short L3");
-					}
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012262");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Circuit Short L1");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Current");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_CIRCUIT_SHORT)
+						previousAlarmCode[gun_index] |= ALARM_L1_CIRCUIT_SHORT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L1_CIRCUIT_SHORT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT) != (previousAlarmCode[gun_index] & ALARM_L2_CIRCUIT_SHORT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011036");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Rotary switch fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012301");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Circuit Short L2");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Rotary switch");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_CIRCUIT_SHORT)
+						previousAlarmCode[gun_index] |= ALARM_L2_CIRCUIT_SHORT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L2_CIRCUIT_SHORT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
+
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_CIRCUIT_SHORT) != (previousAlarmCode[gun_index] & ALARM_L3_CIRCUIT_SHORT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_CIRCUIT_SHORT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_CIRCUIT_SHORT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "011010");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "AC output relay driving fault");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012302");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Circuit Short L3");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Relay");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_CIRCUIT_SHORT)
+						previousAlarmCode[gun_index] |= ALARM_L3_CIRCUIT_SHORT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_L3_CIRCUIT_SHORT;
 				}
-				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT) != (previousAlarmCode[gun_index] & ALARM_ROTATORY_SWITCH_FAULT))
 				{
-					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[0].timestamp);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].trigger, "Alerting");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].actualValue, "true");
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techcode, "012305");
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].techInfo, "Meter communication timeout");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011036");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Rotary switch fault");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].eventNotificationType, "HardWiredNotification");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Rotary switch");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
 
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].component.name, "Meter");
-					ShmOCPP20Data->NotifyEvent.eventData[0].component.evse.connectorId = (gun_index+1);
-					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[0].variable.name, "Problem");
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
 
-					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_ROTATORY_SWITCH_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_ROTATORY_SWITCH_FAULT;
 				}
-				else
-				{}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT) != (previousAlarmCode[gun_index] & ALARM_RELAY_DRIVE_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011010");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC output relay driving fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Relay");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_RELAY_DRIVE_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_RELAY_DRIVE_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT) != (previousAlarmCode[gun_index] & ALARM_METER_TIMEOUT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012305");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Meter communication timeout");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Meter");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_TIMEOUT)
+						previousAlarmCode[gun_index] |= ALARM_METER_TIMEOUT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_METER_TIMEOUT;
+				}
+
+				if(idxEvent > 0)
+					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
 			}
 
 

+ 601 - 91
EVSE/Projects/AW-Regular/Apps/Module_AlarmDetect.c

@@ -71,8 +71,9 @@ void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 struct OCPP16Data				*ShmOCPP16Data;
+struct OCPP20Data				*ShmOCPP20Data;
 struct Charger					*ShmCharger;
-
+unsigned long					previousAlarmCode[AC_QUANTITY];
 
 int StoreLogMsg(const char *fmt, ...)
 {
@@ -210,6 +211,20 @@ int InitShareMemory()
 	else
 	{}
 
+   	//creat ShmOCPP20Data
+   	if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data),  0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+	else
+	{}
+
     return result;
 }
 
@@ -241,6 +256,14 @@ void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
 	dest[cnt] = 0;
 }
 
+void getNowDatetime(uint8_t *data)
+{
+	time_t t = time(NULL);
+	struct tm tm = *localtime(&t);
+
+	sprintf((char*)data, "%04d-%02d-%02dT%02d:%02d:%02dZ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
 //==========================================
 // Main process
 //==========================================
@@ -928,100 +951,587 @@ int main(void)
 			//=====================================
 			// OCPP error code message
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverVoltage");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE)
+			if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "UnderVoltage");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverCurrentFailure");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "HighTemperature");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "GroundFailure");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "CpError");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "ACLeakage");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "DCLeakage");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "McuTestFail");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "HandshakeTimeout");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "EmergencyStop");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayWelding");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "LeakageModuleFail");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "ShutterFault");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "ConnectorLockFailure");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "PowerDrop");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "CircuitShort");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RotatorySwitchFault");
-			}
-			else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
-			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayDriveFault");
+				if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverVoltage");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012200");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "UnderVoltage");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012203");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverCurrentFailure");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012216");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "HighTemperature");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012223");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "GroundFailure");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012256");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "023703");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "CpError");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012233");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "ACLeakage");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012233");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "DCLeakage");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012257");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "McuTestFail");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "HandshakeTimeout");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "HandshakeTimeout");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012251");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "EmergencyStop");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011009");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RelayWelding");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011004");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "LeakageModuleFail");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011034");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "ShutterFault");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "ConnectorLockFailure");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011027");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012212");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "PowerDrop");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012262");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "CircuitShort");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011036");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RotatorySwitchFault");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "011010");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "RelayDriveFault");
+				}
+				else
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError");
+					memset(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode, 0x00, ARRAY_SIZE(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode));
+				}
 			}
-			else
+			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 			{
-				sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError");
-				memset(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode, 0x00, ARRAY_SIZE(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode));
+				uint8_t idxEvent = 0;
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_OVER_VOLTAGE))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012200");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input OVP");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_OVER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_OVER_VOLTAGE;
+				}				
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE) != (previousAlarmCode[gun_index] & ALARM_UNDER_VOLTAGE))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012203");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input UVP");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE)
+						previousAlarmCode[gun_index] |= ALARM_UNDER_VOLTAGE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_UNDER_VOLTAGE;
+				}				
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT) != (previousAlarmCode[gun_index] & ALARM_OVER_CURRENT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012216");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System AC output OCP L1");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT)
+						previousAlarmCode[gun_index] |= ALARM_OVER_CURRENT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_OVER_CURRENT;
+				}			
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE) != (previousAlarmCode[gun_index] & ALARM_OVER_TEMPERATURE))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012223");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System ambient/inlet OTP");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Temperature");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE)
+						previousAlarmCode[gun_index] |= ALARM_OVER_TEMPERATURE;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_OVER_TEMPERATURE;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL) != (previousAlarmCode[gun_index] & ALARM_GROUND_FAIL))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012256");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC Ground Fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Ground(PE)");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL)
+						previousAlarmCode[gun_index] |= ALARM_GROUND_FAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_GROUND_FAIL;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR) != (previousAlarmCode[gun_index] & ALARM_CP_ERROR))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "023703");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "pilot fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Control pilot");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR)
+						previousAlarmCode[gun_index] |= ALARM_CP_ERROR;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CP_ERROR;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC) != (previousAlarmCode[gun_index] & ALARM_CURRENT_LEAK_AC))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012233");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID trip");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC)
+						previousAlarmCode[gun_index] |= ALARM_CURRENT_LEAK_AC;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CURRENT_LEAK_AC;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC) != (previousAlarmCode[gun_index] & ALARM_CURRENT_LEAK_DC))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012233");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID trip");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC)
+						previousAlarmCode[gun_index] |= ALARM_CURRENT_LEAK_DC;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CURRENT_LEAK_DC;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL) != (previousAlarmCode[gun_index] & ALARM_MCU_TESTFAIL))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012257");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "MCU self-test Fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "MCU");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL)
+						previousAlarmCode[gun_index] |= ALARM_MCU_TESTFAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_MCU_TESTFAIL;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT) != (previousAlarmCode[gun_index] & ALARM_HANDSHAKE_TIMEOUT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "HandshakeTimeout");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "HandshakeTimeout");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Operation");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
+						previousAlarmCode[gun_index] |= ALARM_HANDSHAKE_TIMEOUT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_HANDSHAKE_TIMEOUT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) != (previousAlarmCode[gun_index] & ALARM_EMERGENCY_STOP))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012251");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Emergency stop");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Button");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
+						previousAlarmCode[gun_index] |= ALARM_EMERGENCY_STOP;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_EMERGENCY_STOP;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING) != (previousAlarmCode[gun_index] & ALARM_RELAY_WELDING))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011009");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC output relay welding");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Relay");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING)
+						previousAlarmCode[gun_index] |= ALARM_RELAY_WELDING;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_RELAY_WELDING;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL) != (previousAlarmCode[gun_index] & ALARM_LEAK_MODULE_FAIL))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011004");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "RCD/CCID self-test fail");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "CCID");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL)
+						previousAlarmCode[gun_index] |= ALARM_LEAK_MODULE_FAIL;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_LEAK_MODULE_FAIL;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT) != (previousAlarmCode[gun_index] & ALARM_SHUTTER_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011034");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Shutter fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Shutter");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_SHUTTER_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_SHUTTER_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT) != (previousAlarmCode[gun_index] & ALARM_LOCKER_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011027");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC connector lock fail");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Locker");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_LOCKER_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_LOCKER_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP) != (previousAlarmCode[gun_index] & ALARM_POWER_DROP))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012212");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "System L1 input drop");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Voltage");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP)
+						previousAlarmCode[gun_index] |= ALARM_POWER_DROP;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_POWER_DROP;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT) != (previousAlarmCode[gun_index] & ALARM_CURRENT_SHORT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012262");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Circuit Short L1");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Current");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT)
+						previousAlarmCode[gun_index] |= ALARM_CURRENT_SHORT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CURRENT_SHORT;
+				}				
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT) != (previousAlarmCode[gun_index] & ALARM_ROTATORY_SWITCH_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011036");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Rotary switch fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Rotary switch");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_ROTATORY_SWITCH_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_ROTATORY_SWITCH_FAULT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT) != (previousAlarmCode[gun_index] & ALARM_RELAY_DRIVE_FAULT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "011010");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "AC output relay driving fault");
+
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Relay");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT)
+						previousAlarmCode[gun_index] |= ALARM_RELAY_DRIVE_FAULT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_RELAY_DRIVE_FAULT;
+				}
+
+				if(idxEvent > 0)
+					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
 			}
+			
+
 
 			//=====================================
 			// Latch alarm recover in state A