Forráskód Böngészése

Merge branch 'master' into DO360

Wendell 2 éve
szülő
commit
1f8ef360ab
100 módosított fájl, 8330 hozzáadás és 3166 törlés
  1. 80 15
      EVSE/Modularization/ocpp20/MessageHandler.c
  2. 349 79
      EVSE/Modularization/ocppfiles/MessageHandler.c
  3. 3 0
      EVSE/Modularization/ocppfiles/MessageHandler.h
  4. 164 243
      EVSE/Modularization/ocppfiles/Module_OcppBackend.c
  5. 368 98
      EVSE/Modularization/ocppph/MessageHandler.c
  6. 3 0
      EVSE/Modularization/ocppph/MessageHandler.h
  7. 171 244
      EVSE/Modularization/ocppph/Module_OcppBackend.c
  8. 5 5
      EVSE/Projects/AW-CCS/Apps/main.c
  9. 4 4
      EVSE/Projects/AX80/Apps/main.c
  10. 1 0
      EVSE/Projects/DD360/Apps/CSU/Ethernet.c
  11. 10 7
      EVSE/Projects/DD360/Apps/CSU/Primary.c
  12. 19 5
      EVSE/Projects/DD360/Apps/CSU/RFID.c
  13. 162 248
      EVSE/Projects/DD360/Apps/CSU/main.c
  14. 112 6
      EVSE/Projects/DD360/Apps/Config.h
  15. 113 1
      EVSE/Projects/DD360/Apps/DataBase/DataBase.c
  16. 3 1
      EVSE/Projects/DD360/Apps/DataBase/DataBase.h
  17. 5 5
      EVSE/Projects/DD360/Apps/Define/define.c
  18. 110 65
      EVSE/Projects/DD360/Apps/Define/define.h
  19. 1 15
      EVSE/Projects/DD360/Apps/Makefile
  20. 804 60
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.c
  21. 120 3
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.h
  22. 14 2
      EVSE/Projects/DD360/Apps/ModuleEvComm/Ev_Comm.c
  23. 154 43
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvRxComm.c
  24. 5 2
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c
  25. 24 24
      EVSE/Projects/DD360/Apps/ModuleInternalComm/FanBoard.c
  26. 6 1
      EVSE/Projects/DD360/Apps/ModuleInternalComm/LEDlight.c
  27. 56 14
      EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c
  28. 258 301
      EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.c
  29. 278 4
      EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.h
  30. 11 2
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c
  31. 78 9
      EVSE/Projects/DD360/Apps/ReadCmdline.c
  32. 5 1
      EVSE/Projects/DD360/Apps/SelectGun/SelectGun.h
  33. 44 7
      EVSE/Projects/DD360/Apps/ShareMemory/shmMem.c
  34. 1 0
      EVSE/Projects/DD360/Apps/ShareMemory/shmMem.h
  35. BIN
      EVSE/Projects/DD360/Apps/UnsafetyOutputTask
  36. BIN
      EVSE/Projects/DD360/Images/ramdisk.gz
  37. BIN
      EVSE/Projects/DD360/output/DoComm
  38. BIN
      EVSE/Projects/DD360/output/FactoryConfig
  39. BIN
      EVSE/Projects/DD360/output/Module_ChkSysTask
  40. BIN
      EVSE/Projects/DD360/output/Module_DoComm
  41. BIN
      EVSE/Projects/DD360/output/Module_EvComm
  42. BIN
      EVSE/Projects/DD360/output/Module_EventLogging
  43. BIN
      EVSE/Projects/DD360/output/Module_InternalComm
  44. BIN
      EVSE/Projects/DD360/output/Module_LcmControl
  45. BIN
      EVSE/Projects/DD360/output/Module_PrimaryComm
  46. BIN
      EVSE/Projects/DD360/output/Module_UpdateFW
  47. BIN
      EVSE/Projects/DD360/output/ReadCmdline
  48. BIN
      EVSE/Projects/DD360/output/UnsafetyOutputTask
  49. BIN
      EVSE/Projects/DD360/output/main
  50. 1 0
      EVSE/Projects/DD360Audi/Apps/CSU/Ethernet.c
  51. 10 7
      EVSE/Projects/DD360Audi/Apps/CSU/Primary.c
  52. 19 5
      EVSE/Projects/DD360Audi/Apps/CSU/RFID.c
  53. 162 248
      EVSE/Projects/DD360Audi/Apps/CSU/main.c
  54. 112 6
      EVSE/Projects/DD360Audi/Apps/Config.h
  55. 113 1
      EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.c
  56. 3 1
      EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.h
  57. 5 5
      EVSE/Projects/DD360Audi/Apps/Define/define.c
  58. 110 65
      EVSE/Projects/DD360Audi/Apps/Define/define.h
  59. 1 15
      EVSE/Projects/DD360Audi/Apps/Makefile
  60. 804 60
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c
  61. 120 3
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h
  62. 14 2
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Ev_Comm.c
  63. 154 43
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c
  64. 5 2
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c
  65. 24 24
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/FanBoard.c
  66. 6 1
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/LEDlight.c
  67. 56 14
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c
  68. 258 301
      EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c
  69. 278 4
      EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.h
  70. 11 2
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c
  71. 78 9
      EVSE/Projects/DD360Audi/Apps/ReadCmdline.c
  72. 5 1
      EVSE/Projects/DD360Audi/Apps/SelectGun/SelectGun.h
  73. 44 7
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c
  74. 1 0
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.h
  75. 1 0
      EVSE/Projects/DD360ComBox/Apps/CSU/Ethernet.c
  76. 10 7
      EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c
  77. 19 5
      EVSE/Projects/DD360ComBox/Apps/CSU/RFID.c
  78. 162 248
      EVSE/Projects/DD360ComBox/Apps/CSU/main.c
  79. 112 6
      EVSE/Projects/DD360ComBox/Apps/Config.h
  80. 113 1
      EVSE/Projects/DD360ComBox/Apps/DataBase/DataBase.c
  81. 3 1
      EVSE/Projects/DD360ComBox/Apps/DataBase/DataBase.h
  82. 5 5
      EVSE/Projects/DD360ComBox/Apps/Define/define.c
  83. 110 65
      EVSE/Projects/DD360ComBox/Apps/Define/define.h
  84. 1 15
      EVSE/Projects/DD360ComBox/Apps/Makefile
  85. 804 60
      EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.c
  86. 120 3
      EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.h
  87. 14 2
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Ev_Comm.c
  88. 154 43
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvRxComm.c
  89. 5 2
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvTxComm.c
  90. 24 24
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/FanBoard.c
  91. 6 1
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/LEDlight.c
  92. 56 14
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/RelayBoard.c
  93. 258 301
      EVSE/Projects/DD360ComBox/Apps/ModuleLcmCtrl/Module_LcmControl.c
  94. 278 4
      EVSE/Projects/DD360ComBox/Apps/ModuleLcmCtrl/Module_LcmControl.h
  95. 11 2
      EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.c
  96. 78 9
      EVSE/Projects/DD360ComBox/Apps/ReadCmdline.c
  97. 5 1
      EVSE/Projects/DD360ComBox/Apps/SelectGun/SelectGun.h
  98. 44 7
      EVSE/Projects/DD360ComBox/Apps/ShareMemory/shmMem.c
  99. 1 0
      EVSE/Projects/DD360ComBox/Apps/ShareMemory/shmMem.h
  100. 1 0
      EVSE/Projects/define.h

+ 80 - 15
EVSE/Modularization/ocpp20/MessageHandler.c

@@ -2108,7 +2108,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variable.name, "OfflineThreshold");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableCharacteristics.unit, "Seconds");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].value, "30");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold]);
@@ -2332,7 +2332,7 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.maxLimit = 40;
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]);
-		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, "%s", ShmSysConfigAndInfo->SysConfig.OcppSecurityPassword);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, "%s", (strlen((char*)ShmSysConfigAndInfo->SysConfig.OcppSecurityPassword)>0?(char*)ShmSysConfigAndInfo->SysConfig.OcppSecurityPassword:"00000000"));
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword]);
 
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].component.name, "SecurityCtrlr");
@@ -7351,7 +7351,7 @@ void CheckSystemValue(void)
 
 		}
 
-		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 5) &&
+		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 5) && (ShmOCPP20Data->MsMsg.bits.ResetConf != ON) &&
 		   ((cpinitateMsg.bits[gun_index].StatusNotificationReq == ON) || (cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq == ON) ||
 		   ((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].value, "TRUE") == 0) &&
 			(getDiffSecNow(clientTime.StatusNotification[gun_index]) >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableAttribute[0].value)))))
@@ -9606,8 +9606,9 @@ int sendNotifyReportRequest()
 			json_object_object_add(variableCharacteristics, "dataType", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.dataType));
 			json_object_object_add(variableCharacteristics, "minLimit", json_object_new_double(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.minLimit));
 			json_object_object_add(variableCharacteristics, "maxLimit", json_object_new_double(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.maxLimit));
+			json_object_object_add(variableCharacteristics, "supportsMonitoring", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.supportsMonitoring));
 			json_object_object_add(reportData, "variableCharacteristics",variableCharacteristics);
-
+			DEBUG_INFO("+++++++++++++++++++-->VariableName: %s\n", ShmOCPP20Data->NotifyReport.reportData[idxReport].variable.name);
 			for(int idxAttr=0;idxAttr<ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute);idxAttr++)
 			{
 				if(strlen((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value) > 0)
@@ -9621,6 +9622,27 @@ int sendNotifyReportRequest()
 
 					json_object_array_add(variableAttributes, variableAttribute);
 				}
+				/*else
+				{
+					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
+					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]);
+					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value, "%s", "0");
+					json_object *variableAttribute = json_object_new_object();q1314qgrh
+					//if(strlen((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type)==0)
+					DEBUG_INFO("AAAAAAAAAAAAAAAAA\n");
+					json_object_object_add(variableAttribute, "type", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type));
+					DEBUG_INFO("BBBBBBBBBBBBBBBBBBB\n");
+					json_object_object_add(variableAttribute, "value", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value));
+					DEBUG_INFO("CCCCCCCCCCCCCCCCCCCCC\n");
+					json_object_object_add(variableAttribute, "mutability", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].mutability));
+					DEBUG_INFO("DDDDDDDDDDDDDDDDDDDDDD\n");
+					json_object_object_add(variableAttribute, "persistent", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].persistent));
+					DEBUG_INFO("EEEEEEEEEEEEEEEEEEE\n");
+					json_object_object_add(variableAttribute, "constant", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].constant));
+					DEBUG_INFO("FFFFFFFFFFFFFFFFFFF\n");
+					json_object_array_add(variableAttributes, variableAttribute);
+					DEBUG_INFO("GGGGGGGGGGGGGGGGGGGGG\n");
+				}*/
 			}
 			json_object_object_add(reportData, "variableAttribute", variableAttributes);
 
@@ -14914,7 +14936,6 @@ int handleGetReportRequest(char *uuid, char *payload)
 		{
 			ShmOCPP20Data->GetReport.requestId = json_object_get_int(json_object_object_get(GetReport, "requestId"));
 		}
-
 		// Optional data
 		if(json_object_object_get(GetReport, "componentCriteria") != NULL)
 		{
@@ -14941,7 +14962,7 @@ int handleGetReportRequest(char *uuid, char *payload)
 
 						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse") != NULL)
 						{
-							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "getVariableData"), idx), "component"), "evse"), "id") != NULL)
+							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "id") != NULL)
 							{
 								ShmOCPP20Data->GetReport.componentVariable[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "id"));
 							}
@@ -14971,7 +14992,6 @@ int handleGetReportRequest(char *uuid, char *payload)
 	}
 	json_object_put(GetReport);
 
-
 	/*
 	 * TODO:
 	 * 	1. Response result
@@ -15041,6 +15061,11 @@ int handleGetVariablesRequest(char *uuid, char *payload)
 						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, (char*)ShmOCPP20Data->GetVariables.getVariableData[idx].attributeType);
 					}
 
+					/*if(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType != NULL)
+					{
+						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, "Actual");
+					}*/
+
 					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component") != NULL)
 					{
 						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "name") != NULL)
@@ -15116,6 +15141,7 @@ int handleGetVariablesRequest(char *uuid, char *payload)
 							else
 							{
 								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value);
+								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type);
 							}
 
 							break;
@@ -15950,8 +15976,15 @@ int handleReserveNowRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
-								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].InProgress == 1))
+								{
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
+								}
+								else
+								{
+									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
 							{
@@ -16006,8 +16039,15 @@ int handleReserveNowRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
-								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].InProgress == 1))
+								{
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
+								}
+								else
+								{
+									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) ||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '9'))
 							{
@@ -16061,8 +16101,15 @@ int handleReserveNowRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
-								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].InProgress == 1))
+								{
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
+								}
+								else
+								{
+									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -16109,8 +16156,15 @@ int handleReserveNowRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
-								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.InProgress == 1))
+								{
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
+								}
+								else
+								{
+									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
+									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -17622,6 +17676,11 @@ int handleSetVariableMonitoringRequest(char *uuid, char *payload)
 				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, (char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type);
 			}
 
+			if(strlen((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type) == 0)
+			{
+				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, "Actual");
+			}
+
 			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "severity") != NULL)
 			{
 				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].severity = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "severity"));
@@ -17754,6 +17813,11 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 					strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeType);
 				}
 
+				if(strlen((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType) == 0)
+				{
+					strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType, "Actual");
+				}
+
 				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeValue") != NULL)
 				{
 					sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeValue")));
@@ -18642,6 +18706,7 @@ void handleBootNotificationResponse(char *payload, int gun_index)
 		server_sign = TRUE;
 		server_pending =FALSE;
 		DB_updateBootType(BootReasonEnumType_PowerUp);
+		sendSecurityEventNotificationRequest();
 	}
 	else if(strcmp(statusStr, RegistrationStatusEnumTypeStr[RegistrationStatusEnumType_Pending]) == 0)
 	{

+ 349 - 79
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -62,6 +62,8 @@ static int FirstHeartBeat 							= 0;
 static int FirmwareStatusNotificationStatus 		= FIRMWARE_STATUS_IDLE;  // Idle
 static int DiagnosticsStatusNotificationStatus 		= DIAGNOSTIC_STATUS_IDLE; // Idle
 static char CurrentChargingProfileScheduleStr[30]	= {0};
+static float periousPeriodicPowerConsumption[CONNECTOR_QUANTITY]      = {0};
+static float periousClockPowerConsumption[CONNECTOR_QUANTITY]         = {0};
 
 //========================================
 // OCPP status/previous related variables
@@ -112,6 +114,7 @@ void processUnkownKey(void);
 
 struct InterLock
 {
+	unsigned char isSentUnplug[CONNECTOR_QUANTITY];
 	unsigned char isGetDiagnosticGoing:1;
 	unsigned char isUpdateFirmwareGoing:1;
 }interLock;
@@ -4466,6 +4469,15 @@ int ProcessShareMemory()
 			{
 				gunTotalNumber += 1;
 				gunType[gun_index] = GUN_TYPE_DO;
+				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
+				{
+					if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == gun_index)
+					{
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+						DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption);
+					}
+				}
 
  				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
  				{
@@ -4498,18 +4510,54 @@ int ProcessShareMemory()
  					case Gun_Type_Chademo:
  						gunType[gun_index] = GUN_TYPE_CHAdeMO;
  						DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
+ 						for(int index = 0; index < CHAdeMO_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption);
+							}
+						}
  						break;
  					case Gun_Type_CCS_2:
  						gunType[gun_index] = GUN_TYPE_CCS;
  						DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
+ 						for (int index = 0; index < CCS_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == gun_index)
+							{
+							    periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+							    periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+							    DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption);
+							}
+						}
 						break;
  					case Gun_Type_GB:
  						gunType[gun_index] = GUN_TYPE_GBT;
  						DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
+ 						for (int index = 0; index < GB_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption);
+							}
+						}
 						break;
  					case Gun_Type_AC:
  						gunType[gun_index] = GUN_TYPE_AC;
  						DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
+ 						for (int index = 0; index < AC_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption);
+							}
+						}
 						break;
  					default:
  						DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
@@ -5047,14 +5095,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != ChademoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn != ChademoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "org.openchargealliance.costmsg");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16Data->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						ChademoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus;
@@ -5105,14 +5158,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn != CcsPreviousConnectorPlugIn[index]) )//if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]/*PRE_SYS_MODE[gun_index]*/ )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "org.openchargealliance.costmsg");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16Data->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus;
@@ -5163,14 +5221,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != GbPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn != GbPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "org.openchargealliance.costmsg");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16Data->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus;
@@ -5213,14 +5276,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != DoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn != DoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "org.openchargealliance.costmsg");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16Data->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						DoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus;
@@ -5270,14 +5338,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A))
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "org.openchargealliance.costmsg");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16Data->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
@@ -5731,6 +5804,35 @@ int sendDataTransferRequest(int gun_index)
 	return result;
 }
 
+int sendUnplugByDataTransferRequest(int gun_index)
+{
+	mtrace();
+	char message[1000]={0};
+	char guid[37]={0};
+	char tempdata[65]={0};
+	int result = FAIL;
+
+	random_uuid(guid);
+	sprintf(message,"%d,[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
+			(gun_index+1),
+			MESSAGE_TYPE_CALL,
+			guid,
+			ShmOCPP16Data->DataTransfer[gun_index].VendorId,
+			ShmOCPP16Data->DataTransfer[gun_index].MessageId,
+			ShmOCPP16Data->DataTransfer[gun_index].Data);
+
+	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
+	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
+	{
+		result = PASS;
+		DEBUG_INFO("DataTransfer mapItem pass\n");
+	}
+
+	queue_operation(QUEUE_OPERATION_ADD, guid, message);
+
+	return result;
+}
+
 int sendDiagnosticsStatusNotificationRequest(char *status)
 {
 	mtrace();
@@ -6593,27 +6695,6 @@ int sendStopTransactionRequest(int gun_index)
 	//=================================
 	// Transaction_Begin
 	//=================================
-	if(strstr((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTxnSampledData].ItemData, "Energy.Active.Import.Interval") != NULL)
-	{
-		//============================================ Energy.Active.Import.Interval ================================
-		sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Value, "%.3f", 0.0); // MeterStart is 0~6553.5 kWh
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Context,ReadingContextStr[ReadingContext_Transaction_Begin]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Format,ValueFormatStr[Raw]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Measurand,MeasurandStr[Energy_Active_Import_Interval]);//MeasurandStr[Energy_Active_Export_Interval/*Energy_Reactive_Export_Register*/]);
-
-		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
-		if((gunType[gun_index] == GUN_TYPE_CHAdeMO)||(gunType[gun_index] == GUN_TYPE_CCS)||(gunType[gun_index] == GUN_TYPE_GBT)||(gunType[gun_index] == GUN_TYPE_DO))
-		{
-			strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L3_N]);
-		}
-		else
-		{
-			strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L1_N]);
-		}
-
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Location,LocationStr[Location_Outlet]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Unit,UnitOfMeasureStr[UnitOfMeasure_kWh]);
-	}
 
 	//=================================
 	// Transaction_End
@@ -6747,7 +6828,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
 				}
 			}// END OF CHAdeMO_QUANTITY
 
@@ -6769,7 +6851,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
 				}
 			}// END OF CCS_QUANTITY
 
@@ -6791,7 +6874,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
 				}
 			}// END OF GB_QUANTITY
 
@@ -6805,7 +6889,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
 				}
 			}
 
@@ -6827,7 +6912,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
 				}
 			}// END OF AC_QUANTITY
 
@@ -7722,7 +7808,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF FOR CHAdeMO_QUANTITY
 
@@ -7743,7 +7842,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-				   sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF CCS_QUANTITY
 
@@ -7764,7 +7876,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy);
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF GB_QUANTITY
 
@@ -7778,7 +7903,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy);
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			}
 
@@ -7799,7 +7937,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16Data->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			 }
 
@@ -13189,8 +13340,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
 							{
@@ -13245,8 +13403,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) ||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '9'))
 							{
@@ -13300,8 +13465,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -13348,8 +13520,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -15029,6 +15208,79 @@ void *UpdateFirmwareProcess(void *data)
 			retriesInt--;
 		}while((isSuccess == 0)&&(retriesInt >= 0));
 	}
+	else if(strncmp(locationstr,"sftp", 4) == 0) // sftp
+	{
+		memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
+		memset(temp, 0, ARRAY_SIZE(temp));
+		//DEBUG_INFO("locationstr=%s\n",locationstr);
+		strcpy(ftpbuf, locationstr);
+		int ftppathlen=strlen(ftpbuf);
+		int i=1;
+		char filenametemp[50];
+		while(i < ftppathlen)
+		{
+			int len=ftppathlen-i;
+			if(ftpbuf[len]== 47) // '/' ascii code: 47
+			{
+				DEBUG_INFO(" compare '/' all right\n");
+				break;
+			}
+
+			i=i+1;
+		}
+
+		memset(filenametemp, 0, ARRAY_SIZE(filenametemp));
+		strncpy(filenametemp, ftpbuf+(ftppathlen-i+1), i+1);
+		filenametemp[i+1] = 0;
+		strncpy(temp, ftpbuf, ftppathlen-i+1);
+
+		pch=strchr(temp,'@');
+		if(pch==NULL)
+		{
+			sscanf(temp,"%[^:]:%*2[/]%[^:]:%i/%[a-zA-Z0-9._/-]",
+							 protocol, host, &port, path);
+			strcpy(user,"anonymous");
+			strcpy(password,"");
+		}
+		else
+		{
+			sscanf(temp,"%[^:]:%*2[/]%[^@]@%[^:]:%i/%199[^\n]",
+					protocol, user, host, &port, path);
+		}
+
+		sscanf(host,"%[^/]%s",host1, path1);
+		sprintf(ftppath,"%s:/%s", host,path);
+
+		if(port == 0)
+		{
+			port = 21;
+		}
+
+		do
+		{
+			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
+			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			sleep(1);
+
+			isSuccess = sftpDownLoadFile(host1, user, port, ftppath, filenametemp, locationstr);
+			if(!isSuccess)
+			{
+				//BulldogUtil.sleepMs(interval*1000);
+				DEBUG_INFO("Update firmware request and download file fail.\n");
+				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
+				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Idle]);
+				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			}
+			else
+			{
+				sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
+				ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			}
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
+	}
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
 	{
     	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
@@ -20143,6 +20395,39 @@ int httpDownLoadFile(char *location, char *path, char *filename,char *url)
 	return result;
 }
 
+int sftpDownLoadFile(char *location, char *user, int port, char *path, char *filename,char *url)
+{
+	int result = TRUE;
+	char rmFileCmd[100]={0};
+	char FilePath[100]={0};
+	char ftpbuf[200];
+	int systemresult;
+
+	sprintf(FilePath,"/mnt/%s",filename);
+	system("ping 8.8.8.8 &");
+
+	if((access(FilePath,F_OK))!=-1)
+	{
+		DEBUG_INFO("filename=%s exist.\n",FilePath);
+		sprintf(rmFileCmd,"rm -f %s",FilePath);
+		system(rmFileCmd);
+	}
+
+	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
+	sprintf(ftpbuf,"timeout -t 360 scp -i /root/.ssh/id_rsa_bear -P %d %s@%s%s /mnt/%s", port, user, path, filename, filename);
+	DEBUG_INFO("Download command: %s\n",ftpbuf);
+
+	systemresult = system(ftpbuf);
+	if(systemresult != 0)
+	{
+		DEBUG_WARN("scp error!\n");
+		result = FALSE;
+	}
+	system("pkill ping");
+
+	return result;
+}
+
 int ftpDownLoadFile(char *location, char *user, char *password, int port, char *path, char *filename,char *url)
 {
 	int result = TRUE;
@@ -20453,6 +20738,11 @@ void GetStartTransactionIdTag(int gun_index)
 	strcpy((char *)StartTransactionIdTagTemp, (const char *)ShmOCPP16Data->StartTransaction[gun_index].IdTag);
 }
 
+int GetStartTransactionId(int gun_index)
+{
+	return ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId;
+}
+
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction)
 {
 	char ch;
@@ -20724,26 +21014,6 @@ void storeTempStopTransaction(int gun_index)
 	//1. Transaction_Begin
 	//=================================
 	//============================== Energy.Active.Import.Interval ===========================================
-	if(strstr((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTxnSampledData].ItemData, "Energy.Active.Import.Interval") != NULL)
-	{
-		sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Value, "%.3f", 0.0); // MeterStart is 0~6553.5 kWh
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Context,ReadingContextStr[ReadingContext_Transaction_Begin]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Format,ValueFormatStr[Raw]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Measurand,MeasurandStr[Energy_Active_Import_Interval]);//MeasurandStr[Energy_Active_Export_Interval/*Energy_Reactive_Export_Register*/]);
-
-		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
-		if((gunType[gun_index] == GUN_TYPE_CHAdeMO)||(gunType[gun_index] == GUN_TYPE_CCS)||(gunType[gun_index] == GUN_TYPE_GBT)||(gunType[gun_index] == GUN_TYPE_DO))
-		{
-			strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L3_N]);
-		}
-		else
-		{
-			strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L1_N]);
-		}
-
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Location,LocationStr[Location_Outlet]);
-		strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Unit,UnitOfMeasureStr[UnitOfMeasure_kWh]);
-	}
 
 	//=================================
 	//2. Transaction_End
@@ -20878,7 +21148,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF CHAdeMO_QUANTITY
 
@@ -20900,7 +21170,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF CCS_QUANTITY
 
@@ -20922,7 +21192,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF GB_QUANTITY
 
@@ -20936,7 +21206,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[1].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}
 
@@ -20958,7 +21228,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16Data->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF AC_QUANTITY
 

+ 3 - 0
EVSE/Modularization/ocppfiles/MessageHandler.h

@@ -465,6 +465,7 @@ void GetStartTransactionIdTag(int gun_index);
 int sendAuthorizeRequest(int gun_index);
 int sendBootNotificationRequest(void);
 int sendDataTransferRequest(int gun_index);
+int sendUnplugByDataTransferRequest(int gun_index);
 int sendFirmwareVersionByDataTransfer(void);
 int sendDiagnosticsStatusNotificationRequest(char *status);
 int sendFirmwareStatusNotificationRequest(char *status);
@@ -579,6 +580,7 @@ int ftpDownLoadFile(char *location, char *user, char *password, int port, char *
 void *UpdateFirmwareProcess(void* data);
 void* GetDiagnosticsProcess(void* data);
 int httpUploadFile(char *location, char *path, char *filename,char *url);
+int sftpDownLoadFile(char *location, char *user, int port, char *path, char *filename,char *url);
 int ftpUploadFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename);
 void LWS_Send(char * str);
 void LWS_SendNow(char * str);
@@ -587,6 +589,7 @@ int GetOcppServerURL();
 int GetOcppPath();
 int GetOcppPort();
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction);
+int GetStartTransactionId(int gun_index);
 void SetTransactionIdZero(int transactionId);
 void GetChargingProfileRequest(int gunindex);
 void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[]);

+ 164 - 243
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -918,272 +918,193 @@ int showqueue()
 	return TRUE;
 }
 
-int sentqueue(){
+int sentqueue()
+{
+	int result = FAIL;
+	struct stat stats;
 	FILE *fp;
-	int result = FALSE; // 1: TRUE  0:FALSE
-	int temptransactionId = 0, gettransactionId = 0;
-	int tempconnectorId = 0;
-	//int gunIndex = 0;
-	char guid[37]={0};
-	char tempdata[65]={0};
-	char key_value[65]={0};
-	int IsStopTransaction = FALSE;
-	//int IsconnectorIdNULL = FALSE;
-	//int IsIdtagNULL = FALSE;
+	json_object *obj = NULL;
+	json_object *objPayload = NULL;
+	json_object *objData = NULL;
+
+	char cmd[128];
 	char str[QUEUE_MESSAGE_LENGTH]={0};
-	char strcomposite[QUEUE_MESSAGE_LENGTH]={0};
-	char rmFileCmd[100]={0};
-	char connectorStr[2]={0};
-	struct stat stats;
-	char sstr[28]={0};
-	unsigned char IdtagStr[20]={0};
-	unsigned char timestampStr[30]={0};
-	int tempmeterStart = 0;
-	int tempreservationId = 0;
-	int c = 0;
-	char *loc;
+	char queueData[QUEUE_MESSAGE_LENGTH]={0};
+	char payload[QUEUE_MESSAGE_LENGTH]={0};
+	char key_value[65]={0};
+	char hashData[65]={0};
+	char action[32];
+	char guid[37];
+	uint8_t	connectorId;
 
 	DEBUG_INFO("Sent queue.\n");
 
 	stat("/Storage/OCPP", &stats);
 
 	// Check for directory existence
-	if (S_ISDIR(stats.st_mode) == 1)
-	{
-		//DEBUG_INFO("\n OCPP directory exist \n");
-	}
-	else
+	if (S_ISDIR(stats.st_mode) != 1)
 	{
 		//DEBUG_INFO("\n OCPP directory not exist, create dir \n");
-		sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
-		system(rmFileCmd);
+		sprintf(cmd, "mkdir -p /Storage/OCPP");
+		system(cmd);
 	}
 
-	memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
-
-	/* opening file for reading */
-	fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
-	if(fp == NULL) {
-		DEBUG_INFO("Error opening file");
-		return FALSE;
+	if((fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r")) == NULL)
+	{
+		DEBUG_ERROR("Error opening file");
 	}
-
-	if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL ) {
-
-		//---- writing content to stdout ---//
-
-		//*********************Start: StopTransaction***************************/
-		loc = strstr(str, "StopTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			IsStopTransaction = TRUE;
-		}
-
-		memset(connectorStr,0,ARRAY_SIZE(connectorStr));
-		strncpy(connectorStr, str, 1);
-		tempconnectorId = atoi(connectorStr);
-		//*********************End: StopTransaction***************************/
-
-	#if 0
-		//*********************Start:connectorId***************************/
-		loc = strstr(str, "connectorId");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[strlen("connectorId")+2+c] != ',')
-			{
-				sstr[c] = loc[strlen("connectorId")+2+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			tempconnectorId = atoi(sstr);
-		}
-	//	else
-	//	{
-	//		IsconnectorIdNULL = TRUE;
-	//	}
-		//*********************End:connectorId***************************/
-	#endif
-
-		//*********************Start:idTag***************************/
-		loc = strstr(str, "idTag");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-		}
-	//	else
-	//	{
-	//		IsIdtagNULL = TRUE;
-	//	}
-		//*********************End:idTag***************************/
-
-
-		//*********************Start: StartTransaction***************************/
-		loc = strstr(str, "StartTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
+	else
+	{
+		// parse message content
+		if(fgets(str, QUEUE_MESSAGE_LENGTH, fp) != NULL)
 		{
-			// [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
-			//DEBUG_INFO("\n sent queue StartTransaction\n");
-			if(tempconnectorId > 0)
-			{
-				sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
-			}
+			// parse connectorId
+			connectorId = (str[0]-0x30);
+			memcpy(&queueData, &str[2], strlen(str)-2);
 
-			//GUID
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (str[6+c] != '\"')
+			obj = json_tokener_parse(queueData);
+			if(!is_error(obj))
 			{
-				sstr[c] = str[6+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy(guid, sstr);
-
-
-			//Idtag
-			loc = strstr(str, "idTag");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-
-			//meterStart
-			loc = strstr(str, "meterStart");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("meterStart")+2+c] != ',')
+				sprintf(guid, "%s", json_object_get_string(json_object_array_get_idx(obj, 1)));
+				sprintf(action, "%s", json_object_get_string(json_object_array_get_idx(obj, 2)));
+				sprintf(payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 3), JSON_C_TO_STRING_PLAIN));
+				objPayload = json_tokener_parse(payload);
+				if(!is_error(objPayload))
 				{
-					sstr[c] = loc[strlen("meterStart")+2+c];
-					c++;
-				}
-				sstr[c] = '\0';
-				tempmeterStart = atoi(sstr);
-
-			}
+					if(strstr(action, "StartTransaction") != NULL)
+					{
+						if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
+						{
+							//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
+						}
+						else
+						{
+							char idtag[21]={0};
+							char timestamp[36]={0};
+							int meterStart=0;
+							int reservationId=-1;
+							sprintf(hashData, "StartTransaction,%d", (connectorId-1));
+							hashmap_operation(HASH_OP_ADD, guid, hashData);
+
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							if(json_object_object_get(objPayload, "meterStart") != NULL)
+							{
+								meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
+							}
+
+							if(json_object_object_get(objPayload, "reservationId") != NULL)
+							{
+								reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
+							}
+
+							if(json_object_object_get(objPayload, "timestamp") != NULL)
+							{
+								sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
+							}
+
+							FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
+							//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
+						}
+
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+						json_object_put(objPayload);
+					}
+					else if((strstr(action, "MeterValues") != NULL) || strstr(action, "StopTransaction") != NULL)
+					{
+						char idtag[21]={0};
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(json_object_object_get(objPayload, "transactionId") != NULL)
+						{
+							transactionId_org = json_object_get_int(json_object_object_get(objPayload, "transactionId"));
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+							GetStartTransactionIdTag(connectorId-1);
+							transactionId_map = GetTransactionId(connectorId, (unsigned char*)idtag, ((strstr(action, "StopTransaction") != NULL)?YES:NO));
+
+							DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+							DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+							DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+							DEBUG_INFO("original  IdtagStr        = %s\n", "");
+							if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+							{
+								//replace transactionId
+								json_object_object_add(objPayload, "transactionId", json_object_new_int(transactionId_map));
+							}
+							else
+							{
+								transactionId_map = transactionId_org;
+							}
+							DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+						}
+
+						json_object_array_put_idx(obj, 3, objPayload);
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+
+						if(strstr(action, "StopTransaction") != NULL)
+							queueOpInfo.stopTransactionId = transactionId_map;
+					}
+					else
+					{
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(strstr(json_object_get_string(json_object_object_get(objPayload, "messageId")), "ConnectorUnplugged") != NULL)
+						{
+							objData = json_tokener_parse(json_object_get_string(json_object_object_get(objPayload, "data")));
+							if(!is_error(objData))
+							{
+								transactionId_org = json_object_get_int(json_object_object_get(objData, "idTx"));
+
+								//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+								GetStartTransactionIdTag(connectorId-1);
+								transactionId_map = GetTransactionId(connectorId, (unsigned char*)"", NO);
+
+								DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+								DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+								DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+								DEBUG_INFO("original  IdtagStr        = %s\n", "");
+								if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else if((transactionId_map == 0) && (transactionId_org == 0))
+								{
+									//replace transactionId
+									transactionId_map = GetStartTransactionId(connectorId-1);
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else
+								{
+									transactionId_map = transactionId_org;
+								}
+								DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+
+								json_object_object_add(objPayload, "data", json_object_new_string(json_object_to_json_string_ext(objData, JSON_C_TO_STRING_PLAIN)));
+								json_object_array_put_idx(obj, 3, objPayload);
+								LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+							}
+						}
+					}
 
-			//reservationId
-			loc = strstr(str, "reservationId");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("reservationId")+2+c] != ',')
-				{
-					sstr[c] = loc[strlen("reservationId")+2+c];
-					c++;
+					result = PASS;
 				}
-				sstr[c] = '\0';
-				tempreservationId = atoi(sstr);
-
-			}
-
-			//timestamp
-			loc = strstr(str, "timestamp");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("timestamp")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("timestamp")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)timestampStr, sstr);
-
-
-			if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
-			{
-				//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
-			}
-			else
-			{
-				hashmap_operation(HASH_OP_ADD, guid, tempdata);
-				FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
-				//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
 			}
+			json_object_put(obj);
 		}
-		//*********************End: StartTransaction***************************/
-
-
-		//****************transactionId********************/
-		 c=0;
-		 loc = strstr(str, "transactionId");
-		 memset(sstr ,0, ARRAY_SIZE(sstr) );
-		 if(loc != NULL)
-		 {
-			 // Only MeterValue with transactionId & StopTransaction will arrive here
-			 while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
-			 {
-				sstr[c] = loc[strlen("transactionId")+2+c];
-				c++;
-			 }
-
-			sstr[c] = '\0';
-			temptransactionId = atoi(sstr);
-
-
-			//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
-			GetStartTransactionIdTag(tempconnectorId-1);
-			gettransactionId = GetTransactionId(tempconnectorId, IdtagStr, IsStopTransaction);
-
-			DEBUG_INFO("queue map transactionId   = %d\n", gettransactionId);
-			DEBUG_INFO("original  connectorId     = %d\n", tempconnectorId);
-			DEBUG_INFO("original  transactionId   = %d\n", temptransactionId);
-			DEBUG_INFO("original  IdtagStr        = %s\n", IdtagStr);
-			if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
-			{
-				//replace transactionId of metervalue or stopTransaction
-				strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
-				sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
-				strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
-				LWS_Send(strcomposite+2); // skip 2 bytes String -> Connector ID,
-			}
-			else
-			{
-				LWS_Send(str+2);  // skip 2 bytes String -> Connector ID
-				gettransactionId = temptransactionId;
-			}
-
-			DEBUG_INFO("Final transactionId       = %d\n", gettransactionId);
-			if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
-			{
-				queueOpInfo.stopTransactionId = gettransactionId;
-				//SetTransactionIdZero(gettransactionId);
-			}
-		 }
-		 else
-		 {
-			 // MeterValue without transactionId & StartTransaction arrive here
-			 LWS_Send(str+2);
-		 }
-
-		result = TRUE;
-	}
-	else
-	{
-		result = FALSE;
 	}
 	fclose(fp);
+
 	return result;
 }
 

+ 368 - 98
EVSE/Modularization/ocppph/MessageHandler.c

@@ -63,6 +63,8 @@ static int FirstHeartBeat 							= 0;
 static int FirmwareStatusNotificationStatus 		= FIRMWARE_STATUS_IDLE;  // Idle
 static int DiagnosticsStatusNotificationStatus 		= DIAGNOSTIC_STATUS_IDLE; // Idle
 static char CurrentChargingProfileScheduleStr[30]	= {0};
+static float periousPeriodicPowerConsumption[CONNECTOR_QUANTITY]      = {0};
+static float periousClockPowerConsumption[CONNECTOR_QUANTITY]         = {0};
 
 //========================================
 // OCPP status/previous related variables
@@ -113,6 +115,7 @@ void processUnkownKey(void);
 
 struct InterLock
 {
+	unsigned char isSentUnplug[CONNECTOR_QUANTITY];
 	unsigned char isGetDiagnosticGoing:1;
 	unsigned char isUpdateFirmwareGoing:1;
 }interLock;
@@ -3984,6 +3987,15 @@ int ProcessShareMemory()
 			{
 				gunTotalNumber += 1;
 				gunType[gun_index] = GUN_TYPE_DO;
+				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
+				{
+					if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == gun_index)
+					{
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+						DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption);
+					}
+				}
 
  				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
  				{
@@ -4011,28 +4023,64 @@ int ProcessShareMemory()
  			{
 				gunTotalNumber += 1;
 
- 				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
- 				{
- 					case Gun_Type_Chademo:
- 						gunType[gun_index] = GUN_TYPE_CHAdeMO;
- 						DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
- 						break;
- 					case Gun_Type_CCS_2:
- 						gunType[gun_index] = GUN_TYPE_CCS;
- 						DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
+				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
+				{
+					case Gun_Type_Chademo:
+						gunType[gun_index] = GUN_TYPE_CHAdeMO;
+						DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
+						for(int index = 0; index < CHAdeMO_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption);
+							}
+						}
 						break;
- 					case Gun_Type_GB:
- 						gunType[gun_index] = GUN_TYPE_GBT;
- 						DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
+					case Gun_Type_CCS_2:
+						gunType[gun_index] = GUN_TYPE_CCS;
+						DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
+						for (int index = 0; index < CCS_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption);
+							}
+						}
 						break;
- 					case Gun_Type_AC:
- 						gunType[gun_index] = GUN_TYPE_AC;
- 						DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
+					case Gun_Type_GB:
+						gunType[gun_index] = GUN_TYPE_GBT;
+						DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
+						for (int index = 0; index < GB_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption);
+							}
+						}
 						break;
- 					default:
- 						DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
- 						break;
- 				}
+					case Gun_Type_AC:
+						gunType[gun_index] = GUN_TYPE_AC;
+						DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
+						for (int index = 0; index < AC_QUANTITY; index++)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == gun_index)
+							{
+								periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+								periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+								DEBUG_INFO("Gun-%02d PowerConsumption: %.3f\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption);
+							}
+						}
+						break;
+					default:
+						DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
+						break;
+				}
  			}
 		}
 	}
@@ -4567,14 +4615,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != ChademoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn != ChademoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						ChademoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus;
@@ -4625,14 +4678,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn != CcsPreviousConnectorPlugIn[index]) )//if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]/*PRE_SYS_MODE[gun_index]*/ )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus;
@@ -4683,14 +4741,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != GbPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn != GbPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus;
@@ -4733,14 +4796,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != DoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn != DoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						DoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus;
@@ -4790,14 +4858,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A))
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
@@ -5262,6 +5335,35 @@ int sendDataTransferRequest(int gun_index)
 	return result;
 }
 
+int sendUnplugByDataTransferRequest(int gun_index)
+{
+	mtrace();
+	char message[1000]={0};
+	char guid[37]={0};
+	char tempdata[65]={0};
+	int result = FAIL;
+
+	random_uuid(guid);
+	sprintf(message,"%d,[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
+			(gun_index+1),
+			MESSAGE_TYPE_CALL,
+			guid,
+			ShmOCPP16DataPH->DataTransfer[gun_index].VendorId,
+			ShmOCPP16DataPH->DataTransfer[gun_index].MessageId,
+			ShmOCPP16DataPH->DataTransfer[gun_index].Data);
+
+	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
+	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
+	{
+		result = PASS;
+		DEBUG_INFO("DataTransfer mapItem pass\n");
+	}
+
+	queue_operation(QUEUE_OPERATION_ADD, guid, message);
+
+	return result;
+}
+
 int sendDiagnosticsStatusNotificationRequest(char *status)
 {
 	mtrace();
@@ -6126,27 +6228,6 @@ int sendStopTransactionRequest(int gun_index)
 	//=================================
 	// Transaction_Begin
 	//=================================
-	if(strstr((char*)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[StopTxnSampledData].ItemData, "Energy.Active.Import.Interval") != NULL)
-	{
-		//============================================ Energy.Active.Import.Interval ================================
-		sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Value, "%.3f", 0.0); // MeterStart is 0~6553.5 kWh
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Context,ReadingContextStr[ReadingContext_Transaction_Begin]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Format,ValueFormatStr[Raw]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Measurand,MeasurandStr[Energy_Active_Import_Interval]);//MeasurandStr[Energy_Active_Export_Interval/*Energy_Reactive_Export_Register*/]);
-
-		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
-		if((gunType[gun_index] == GUN_TYPE_CHAdeMO)||(gunType[gun_index] == GUN_TYPE_CCS)||(gunType[gun_index] == GUN_TYPE_GBT)||(gunType[gun_index] == GUN_TYPE_DO))
-		{
-			strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L3_N]);
-		}
-		else
-		{
-			strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L1_N]);
-		}
-
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Location,LocationStr[Location_Outlet]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Unit,UnitOfMeasureStr[UnitOfMeasure_kWh]);
-	}
 
 	//=================================
 	// Transaction_End
@@ -6280,7 +6361,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
 				}
 			}// END OF CHAdeMO_QUANTITY
 
@@ -6302,7 +6384,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
 				}
 			}// END OF CCS_QUANTITY
 
@@ -6324,7 +6407,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
 				}
 			}// END OF GB_QUANTITY
 
@@ -6338,7 +6422,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
 				}
 			}
 
@@ -6360,7 +6445,8 @@ int sendStopTransactionRequest(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
+					periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
 				}
 			}// END OF AC_QUANTITY
 
@@ -7255,7 +7341,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF FOR CHAdeMO_QUANTITY
 
@@ -7276,7 +7375,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-				   sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF CCS_QUANTITY
 
@@ -7297,7 +7409,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy);
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			} // END OF GB_QUANTITY
 
@@ -7311,7 +7436,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy);
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			}
 
@@ -7332,7 +7470,20 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );
+					if(dataType == ReadingContext_Sample_Clock)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousClockPowerConsumption[gun_index]));
+						periousClockPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+					}
+					else if(dataType == ReadingContext_Sample_Periodic)
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));
+						periousPeriodicPowerConsumption[gun_index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
+					}
+					else
+					{
+						sprintf((char *)ShmOCPP16DataPH->MeterValues[gun_index].MeterValue[0].SampledValue[2].Value, "0.000");
+					}
 				}
 			 }
 
@@ -12695,8 +12846,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
 							{
@@ -12751,8 +12909,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 						{
 							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) ||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '9'))
 							{
@@ -12806,8 +12971,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -12854,8 +13026,15 @@ int handleReserveNowTransactionRequest(char *uuid, char *payload)
 
 							if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
 							{
-								ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
-								strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.InProgress == 1))
+								{
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Occupied]);
+								}
+								else
+								{
+									ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].ReserveNowReq = 1;
+									strcpy(comfirmstr, ReservationStatusStr[ReservationStatus_Accepted]);
+								}
 							}
 							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
 							{
@@ -14530,6 +14709,79 @@ void *UpdateFirmwareProcess(void *data)
 			retriesInt--;
 		}while((isSuccess == 0)&&(retriesInt >= 0));
 	}
+	else if(strncmp(locationstr,"sftp", 4) == 0) // sftp
+	{
+		memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
+		memset(temp, 0, ARRAY_SIZE(temp));
+		//DEBUG_INFO("locationstr=%s\n",locationstr);
+		strcpy(ftpbuf, locationstr);
+		int ftppathlen=strlen(ftpbuf);
+		int i=1;
+		char filenametemp[50];
+		while(i < ftppathlen)
+		{
+			int len=ftppathlen-i;
+			if(ftpbuf[len]== 47) // '/' ascii code: 47
+			{
+				DEBUG_INFO(" compare '/' all right\n");
+				break;
+			}
+
+			i=i+1;
+		}
+
+		memset(filenametemp, 0, ARRAY_SIZE(filenametemp));
+		strncpy(filenametemp, ftpbuf+(ftppathlen-i+1), i+1);
+		filenametemp[i+1] = 0;
+		strncpy(temp, ftpbuf, ftppathlen-i+1);
+
+		pch=strchr(temp,'@');
+		if(pch==NULL)
+		{
+			sscanf(temp,"%[^:]:%*2[/]%[^:]:%i/%[a-zA-Z0-9._/-]",
+							 protocol, host, &port, path);
+			strcpy(user,"anonymous");
+			strcpy(password,"");
+		}
+		else
+		{
+			sscanf(temp,"%[^:]:%*2[/]%[^@]@%[^:]:%i/%199[^\n]",
+					protocol, user, host, &port, path);
+		}
+
+		sscanf(host,"%[^/]%s",host1, path1);
+		sprintf(ftppath,"%s:/%s", host,path);
+
+		if(port == 0)
+		{
+			port = 21;
+		}
+
+		do
+		{
+			sprintf((char*)ShmOCPP16DataPH->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloading]);
+			ShmOCPP16DataPH->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			sleep(1);
+
+			isSuccess = sftpDownLoadFile(host1, user, port, ftppath, filenametemp, locationstr);
+			if(!isSuccess)
+			{
+				//BulldogUtil.sleepMs(interval*1000);
+				DEBUG_INFO("Update firmware request and download file fail.\n");
+				sprintf((char*)ShmOCPP16DataPH->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_DownloadFailed]);
+				ShmOCPP16DataPH->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+				if(retriesInt>0)sleep(retryIntervalInt);else sleep(1);
+				sprintf((char*)ShmOCPP16DataPH->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Idle]);
+				ShmOCPP16DataPH->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			}
+			else
+			{
+				sprintf((char*)ShmOCPP16DataPH->FirmwareStatusNotification.Status, "%s",FirmwareStatusStr[FirmwareStatus_Downloaded]);
+				ShmOCPP16DataPH->SpMsg.bits.FirmwareStatusNotificationReq = 1;
+			}
+			retriesInt--;
+		}while((!isSuccess)&&(retriesInt >= 0));
+	}
     else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
 	{
     	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
@@ -19422,6 +19674,39 @@ int httpDownLoadFile(char *location, char *path, char *filename,char *url)
 	return result;
 }
 
+int sftpDownLoadFile(char *location, char *user, int port, char *path, char *filename,char *url)
+{
+	int result = TRUE;
+	char rmFileCmd[100]={0};
+	char FilePath[100]={0};
+	char ftpbuf[200];
+	int systemresult;
+
+	sprintf(FilePath,"/mnt/%s",filename);
+	system("ping 8.8.8.8 &");
+
+	if((access(FilePath,F_OK))!=-1)
+	{
+		DEBUG_INFO("filename=%s exist.\n",FilePath);
+		sprintf(rmFileCmd,"rm -f %s",FilePath);
+		system(rmFileCmd);
+	}
+
+	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
+	sprintf(ftpbuf,"timeout -t 360 scp -i /root/.ssh/id_rsa_bear -P %d %s@%s%s /mnt/%s", port, user, path, filename, filename);
+	DEBUG_INFO("Download command: %s\n",ftpbuf);
+
+	systemresult = system(ftpbuf);
+	if(systemresult != 0)
+	{
+		DEBUG_WARN("scp error!\n");
+		result = FALSE;
+	}
+	system("pkill ping");
+
+	return result;
+}
+
 int ftpDownLoadFile(char *location, char *user, char *password, int port, char *path, char *filename,char *url)
 {
 	int result = TRUE;
@@ -19682,6 +19967,11 @@ void GetStartTransactionIdTag(int gun_index)
 	strcpy((char *)StartTransactionIdTagTemp, (const char *)ShmOCPP16DataPH->StartTransaction[gun_index].IdTag);
 }
 
+int GetStartTransactionId(int gun_index)
+{
+	return ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId;
+}
+
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction)
 {
 	char ch;
@@ -19953,26 +20243,6 @@ void storeTempStopTransaction(int gun_index)
 	//1. Transaction_Begin
 	//=================================
 	//============================== Energy.Active.Import.Interval ===========================================
-	if(strstr((char*)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[StopTxnSampledData].ItemData, "Energy.Active.Import.Interval") != NULL)
-	{
-		sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Value, "%.3f", 0.0); // MeterStart is 0~6553.5 kWh
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Context,ReadingContextStr[ReadingContext_Transaction_Begin]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Format,ValueFormatStr[Raw]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Measurand,MeasurandStr[Energy_Active_Import_Interval]);//MeasurandStr[Energy_Active_Export_Interval/*Energy_Reactive_Export_Register*/]);
-
-		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
-		if((gunType[gun_index] == GUN_TYPE_CHAdeMO)||(gunType[gun_index] == GUN_TYPE_CCS)||(gunType[gun_index] == GUN_TYPE_GBT)||(gunType[gun_index] == GUN_TYPE_DO))
-		{
-			strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L3_N]);
-		}
-		else
-		{
-			strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Phase,PhaseStr[L1_N]);
-		}
-
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Location,LocationStr[Location_Outlet]);
-		strcpy((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[0].Unit,UnitOfMeasureStr[UnitOfMeasure_kWh]);
-	}
 
 	//=================================
 	//2. Transaction_End
@@ -20107,7 +20377,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF CHAdeMO_QUANTITY
 
@@ -20129,7 +20399,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF CCS_QUANTITY
 
@@ -20151,7 +20421,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF GB_QUANTITY
 
@@ -20165,7 +20435,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[1].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}
 
@@ -20187,7 +20457,7 @@ void storeTempStopTransaction(int gun_index)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy );// PresentChargedEnergy is 0~6553.5 kWh
+					sprintf((char *)ShmOCPP16DataPH->StopTransaction[gun_index].TransactionData[0].SampledValue[2].Value, "%.3f" ,(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption - periousPeriodicPowerConsumption[gun_index]));// PresentChargedEnergy is 0~6553.5 kWh
 				}
 			}// END OF AC_QUANTITY
 

+ 3 - 0
EVSE/Modularization/ocppph/MessageHandler.h

@@ -461,6 +461,7 @@ void GetStartTransactionIdTag(int gun_index);
 int sendAuthorizeRequest(int gun_index);
 int sendBootNotificationRequest(void);
 int sendDataTransferRequest(int gun_index);
+int sendUnplugByDataTransferRequest(int gun_index);
 int sendFirmwareVersionByDataTransfer(void);
 int sendDiagnosticsStatusNotificationRequest(char *status);
 int sendFirmwareStatusNotificationRequest(char *status);
@@ -575,6 +576,7 @@ int ftpDownLoadFile(char *location, char *user, char *password, int port, char *
 void *UpdateFirmwareProcess(void* data);
 void* GetDiagnosticsProcess(void* data);
 int httpUploadFile(char *location, char *path, char *filename,char *url);
+int sftpDownLoadFile(char *location, char *user, int port, char *path, char *filename,char *url);
 int ftpUploadFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename);
 void LWS_Send(char * str);
 void LWS_SendNow(char * str);
@@ -583,6 +585,7 @@ int GetOcppServerURL();
 int GetOcppPath();
 int GetOcppPort();
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction);
+int GetStartTransactionId(int gun_index);
 void SetTransactionIdZero(int transactionId);
 void GetChargingProfileRequest(int gunindex);
 void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[]);

+ 171 - 244
EVSE/Modularization/ocppph/Module_OcppBackend.c

@@ -916,272 +916,199 @@ int showqueue()
 	return TRUE;
 }
 
-int sentqueue(){
+int sentqueue()
+{
+	int result = FAIL;
+	struct stat stats;
 	FILE *fp;
-	int result = FALSE; // 1: TRUE  0:FALSE
-	int temptransactionId = 0, gettransactionId = 0;
-	int tempconnectorId = 0;
-	//int gunIndex = 0;
-	char guid[37]={0};
-	char tempdata[65]={0};
-	char key_value[65]={0};
-	int IsStopTransaction = FALSE;
-	//int IsconnectorIdNULL = FALSE;
-	//int IsIdtagNULL = FALSE;
+	json_object *obj = NULL;
+	json_object *objPayload = NULL;
+	json_object *objData = NULL;
+
+	char cmd[128];
 	char str[QUEUE_MESSAGE_LENGTH]={0};
-	char strcomposite[QUEUE_MESSAGE_LENGTH]={0};
-	char rmFileCmd[100]={0};
-	char connectorStr[2]={0};
-	struct stat stats;
-	char sstr[28]={0};
-	unsigned char IdtagStr[20]={0};
-	unsigned char timestampStr[30]={0};
-	int tempmeterStart = 0;
-	int tempreservationId = 0;
-	int c = 0;
-	char *loc;
+	char queueData[QUEUE_MESSAGE_LENGTH]={0};
+	char payload[QUEUE_MESSAGE_LENGTH]={0};
+	char key_value[65]={0};
+	char hashData[65]={0};
+	char action[32];
+	char guid[37];
+	uint8_t	connectorId;
 
 	DEBUG_INFO("Sent queue.\n");
 
-	stat("/Storage/OCPP_PH", &stats);
+	stat("/Storage/OCPP", &stats);
 
 	// Check for directory existence
-	if (S_ISDIR(stats.st_mode) == 1)
-	{
-		//DEBUG_INFO("\n OCPP directory exist \n");
-	}
-	else
+	if (S_ISDIR(stats.st_mode) != 1)
 	{
 		//DEBUG_INFO("\n OCPP directory not exist, create dir \n");
-		sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP_PH");
-		system(rmFileCmd);
+		sprintf(cmd, "mkdir -p /Storage/OCPP");
+		system(cmd);
 	}
 
-	memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
-
-	/* opening file for reading */
-	fp = fopen("/Storage/OCPP_PH/TransactionRelatedQueue" , "r");
-	if(fp == NULL) {
-		DEBUG_INFO("Error opening file");
-		return FALSE;
+	if((fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r")) == NULL)
+	{
+		DEBUG_ERROR("Error opening file");
 	}
-
-	if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL ) {
-
-		//---- writing content to stdout ---//
-
-		//*********************Start: StopTransaction***************************/
-		loc = strstr(str, "StopTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			IsStopTransaction = TRUE;
-		}
-
-		memset(connectorStr,0,ARRAY_SIZE(connectorStr));
-		strncpy(connectorStr, str, 1);
-		tempconnectorId = atoi(connectorStr);
-		//*********************End: StopTransaction***************************/
-
-	#if 0
-		//*********************Start:connectorId***************************/
-		loc = strstr(str, "connectorId");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[strlen("connectorId")+2+c] != ',')
-			{
-				sstr[c] = loc[strlen("connectorId")+2+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			tempconnectorId = atoi(sstr);
-		}
-	//	else
-	//	{
-	//		IsconnectorIdNULL = TRUE;
-	//	}
-		//*********************End:connectorId***************************/
-	#endif
-
-		//*********************Start:idTag***************************/
-		loc = strstr(str, "idTag");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-		}
-	//	else
-	//	{
-	//		IsIdtagNULL = TRUE;
-	//	}
-		//*********************End:idTag***************************/
-
-
-		//*********************Start: StartTransaction***************************/
-		loc = strstr(str, "StartTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
+	else
+	{
+		// parse message content
+		if(fgets(str, QUEUE_MESSAGE_LENGTH, fp) != NULL)
 		{
-			// [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
-			//DEBUG_INFO("\n sent queue StartTransaction\n");
-			if(tempconnectorId > 0)
-			{
-				sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
-			}
+			// parse connectorId
+			connectorId = (str[0]-0x30);
+			memcpy(&queueData, &str[2], strlen(str)-2);
 
-			//GUID
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (str[6+c] != '\"')
+			obj = json_tokener_parse(queueData);
+			if(!is_error(obj))
 			{
-				sstr[c] = str[6+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy(guid, sstr);
-
-
-			//Idtag
-			loc = strstr(str, "idTag");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-
-			//meterStart
-			loc = strstr(str, "meterStart");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("meterStart")+2+c] != ',')
+				sprintf(guid, "%s", json_object_get_string(json_object_array_get_idx(obj, 1)));
+				sprintf(action, "%s", json_object_get_string(json_object_array_get_idx(obj, 2)));
+				sprintf(payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 3), JSON_C_TO_STRING_PLAIN));
+				objPayload = json_tokener_parse(payload);
+				if(!is_error(objPayload))
 				{
-					sstr[c] = loc[strlen("meterStart")+2+c];
-					c++;
-				}
-				sstr[c] = '\0';
-				tempmeterStart = atoi(sstr);
-
-			}
+					if(strstr(action, "StartTransaction") != NULL)
+					{
+						if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
+						{
+							//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
+						}
+						else
+						{
+							char idtag[21]={0};
+							char timestamp[36]={0};
+							int meterStart=0;
+							int reservationId=-1;
+							sprintf(hashData, "StartTransaction,%d", (connectorId-1));
+							hashmap_operation(HASH_OP_ADD, guid, hashData);
+
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							if(json_object_object_get(objPayload, "meterStart") != NULL)
+							{
+								meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
+							}
+
+							if(json_object_object_get(objPayload, "reservationId") != NULL)
+							{
+								reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
+							}
+
+							if(json_object_object_get(objPayload, "timestamp") != NULL)
+							{
+								sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
+							}
+
+							FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
+							//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
+						}
+
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+						json_object_put(objPayload);
+					}
+					else if((strstr(action, "MeterValues") != NULL) || strstr(action, "StopTransaction") != NULL)
+					{
+						char idtag[21]={0};
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(json_object_object_get(objPayload, "transactionId") != NULL)
+						{
+							transactionId_org = json_object_get_int(json_object_object_get(objPayload, "transactionId"));
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+							GetStartTransactionIdTag(connectorId-1);
+							transactionId_map = GetTransactionId(connectorId, (unsigned char*)idtag, ((strstr(action, "StopTransaction") != NULL)?YES:NO));
+
+							DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+							DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+							DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+							DEBUG_INFO("original  IdtagStr        = %s\n", "");
+							if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+							{
+								//replace transactionId
+								json_object_object_add(objPayload, "transactionId", json_object_new_int(transactionId_map));
+							}
+							else if((transactionId_map == 0) && (transactionId_org == 0))
+							{
+								//replace transactionId
+								transactionId_map = GetStartTransactionId(connectorId-1);
+								json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+							}
+							else
+							{
+								transactionId_map = transactionId_org;
+							}
+							DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+						}
+
+						json_object_array_put_idx(obj, 3, objPayload);
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+
+						if(strstr(action, "StopTransaction") != NULL)
+							queueOpInfo.stopTransactionId = transactionId_map;
+					}
+					else
+					{
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(strstr(json_object_get_string(json_object_object_get(objPayload, "messageId")), "ConnectorUnplugged") != NULL)
+						{
+							objData = json_tokener_parse(json_object_get_string(json_object_object_get(objPayload, "data")));
+							if(!is_error(objData))
+							{
+								transactionId_org = json_object_get_int(json_object_object_get(objData, "idTx"));
+
+
+								//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+								GetStartTransactionIdTag(connectorId-1);
+								transactionId_map = GetTransactionId(connectorId, (unsigned char*)"", NO);
+
+								DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+								DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+								DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+								DEBUG_INFO("original  IdtagStr        = %s\n", "");
+								if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else if((transactionId_map == 0) && (transactionId_org == 0))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(GetStartTransactionId(connectorId-1)));
+								}
+								else
+								{
+									transactionId_map = transactionId_org;
+								}
+								DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+
+								json_object_object_add(objPayload, "data", json_object_new_string(json_object_to_json_string_ext(objData, JSON_C_TO_STRING_PLAIN)));
+								json_object_array_put_idx(obj, 3, objPayload);
+								LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+							}
+						}
+					}
 
-			//reservationId
-			loc = strstr(str, "reservationId");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("reservationId")+2+c] != ',')
-				{
-					sstr[c] = loc[strlen("reservationId")+2+c];
-					c++;
+					result = PASS;
 				}
-				sstr[c] = '\0';
-				tempreservationId = atoi(sstr);
-
-			}
-
-			//timestamp
-			loc = strstr(str, "timestamp");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("timestamp")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("timestamp")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)timestampStr, sstr);
-
-
-			if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
-			{
-				//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
-			}
-			else
-			{
-				hashmap_operation(HASH_OP_ADD, guid, tempdata);
-				FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
-				//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
 			}
+			json_object_put(obj);
 		}
-		//*********************End: StartTransaction***************************/
-
-
-		//****************transactionId********************/
-		 c=0;
-		 loc = strstr(str, "transactionId");
-		 memset(sstr ,0, ARRAY_SIZE(sstr) );
-		 if(loc != NULL)
-		 {
-			 // Only MeterValue with transactionId & StopTransaction will arrive here
-			 while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
-			 {
-				sstr[c] = loc[strlen("transactionId")+2+c];
-				c++;
-			 }
-
-			sstr[c] = '\0';
-			temptransactionId = atoi(sstr);
-
-
-			//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
-			GetStartTransactionIdTag(tempconnectorId-1);
-			gettransactionId = GetTransactionId(tempconnectorId, IdtagStr, IsStopTransaction);
-
-			DEBUG_INFO("queue map transactionId   = %d\n", gettransactionId);
-			DEBUG_INFO("original  connectorId     = %d\n", tempconnectorId);
-			DEBUG_INFO("original  transactionId   = %d\n", temptransactionId);
-			DEBUG_INFO("original  IdtagStr        = %s\n", IdtagStr);
-			if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
-			{
-				//replace transactionId of metervalue or stopTransaction
-				strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
-				sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
-				strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
-				LWS_Send(strcomposite+2); // skip 2 bytes String -> Connector ID,
-			}
-			else
-			{
-				LWS_Send(str+2);  // skip 2 bytes String -> Connector ID
-				gettransactionId = temptransactionId;
-			}
-
-			DEBUG_INFO("Final transactionId       = %d\n", gettransactionId);
-			if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
-			{
-				queueOpInfo.stopTransactionId = gettransactionId;
-				//SetTransactionIdZero(gettransactionId);
-			}
-		 }
-		 else
-		 {
-			 // MeterValue without transactionId & StartTransaction arrive here
-			 LWS_Send(str+2);
-		 }
-
-		result = TRUE;
-	}
-	else
-	{
-		result = FALSE;
 	}
 	fclose(fp);
+
 	return result;
 }
 

+ 5 - 5
EVSE/Projects/AW-CCS/Apps/main.c

@@ -2735,6 +2735,11 @@ int SpawnTask(uint8_t gun_index)
 		}
 
 		system("/root/Module_EventLogging &");
+		system ("/root/Module_AlarmDetect &");
+		system ("/root/Module_InternalComm &");
+		system ("/root/Module_Speaker &");
+		system ("/root/Module_ProduceUtils &");
+		system ("/root/Module_LcmControl &");
 
 		if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0)
 		{
@@ -2745,11 +2750,6 @@ int SpawnTask(uint8_t gun_index)
 			DEBUG_INFO("OCPP URL is empty, need to create a configuration table !!!\n");
 			ocpp_process_start();
 		}
-		system ("/root/Module_AlarmDetect &");
-		system ("/root/Module_InternalComm &");
-		system ("/root/Module_Speaker &");
-		system ("/root/Module_ProduceUtils &");
-		system ("/root/Module_LcmControl &");
 	}
 
 	return PASS;

+ 4 - 4
EVSE/Projects/AX80/Apps/main.c

@@ -4705,6 +4705,7 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EmergencyStop");
+			memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		}
 		else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES))
 		{
@@ -4744,6 +4745,7 @@ void checkStopReason(uint8_t gun_index)
 		else
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other");
+			memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
@@ -5450,8 +5452,7 @@ int main(void)
 					// Alarm event check
 					if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode>0) ||
 						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail ||
-						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP ||
-						ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP)
 					{
 						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_ALARM)
 						{
@@ -6480,8 +6481,7 @@ int main(void)
 
 						if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == 0) &&
 						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail &&
-						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP &&
-						   !ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail)
+						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP)
 						{
 							if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) &&
 								!ShmCharger->gun_info[gun_index].isEmergencyStopReport)

+ 1 - 0
EVSE/Projects/DD360/Apps/CSU/Ethernet.c

@@ -194,6 +194,7 @@ void InitEthernet(void)
     //system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up");
 
     if (pSysConfig->Eth0Interface.EthDhcpClient == 0) {
+        system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
         sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &",
                 pSysConfig->SystemId);
         system(tmpbuf);

+ 10 - 7
EVSE/Projects/DD360/Apps/CSU/Primary.c

@@ -23,7 +23,7 @@ typedef struct StLedConfig {
     uint8_t AcContactor: 1;                     //bit 6,    H: ON,      L:OFF
     uint8_t Reserved: 1;                        //bit 7 reserved
 } LedConfig;
-
+time_t showInfoTimer;
 //------------------------------------------------------------------------------
 static uint8_t checkCabinetEthConnectState(LedConfig *ledConfig)
 {
@@ -217,6 +217,7 @@ static void checkChargingInfoByDC(uint8_t systemStatus)
 
     switch (systemStatus) {
     case S_IDLE:
+    case S_RESERVATION:
         if (isDetectPlugin()) {
             _DetectPlugInTimeout();
             StopSystemTimeoutDet();
@@ -436,12 +437,14 @@ void ChkPrimaryStatus(void)
     }
 
     //DS60-120 add
-    //if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
-    //        ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
-    //    pSysConfig->ShowInformation = YES;
-    //} else {
-    //    pSysConfig->ShowInformation = NO;
-    //}
+    if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
+            ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
+        pSysConfig->ShowInformation = YES;
+        showInfoTimer = time((time_t*)NULL);
+    } else {
+        if ( (time((time_t*)NULL) - showInfoTimer) > 3 )
+            pSysConfig->ShowInformation = NO;
+    }
 
     if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
             !leftBtnPush &&

+ 19 - 5
EVSE/Projects/DD360/Apps/CSU/RFID.c

@@ -16,7 +16,7 @@
 static char *rfidPortName = "/dev/ttyS2";
 
 static bool isCardScan = false;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 static bool canStartCharging(void)
 {
@@ -140,7 +140,8 @@ static void UserScanFunction(void)
             stopReq = i;
         }
 
-        if ((pDcChargingInfo->SystemStatus == S_IDLE &&
+        if (((pDcChargingInfo->SystemStatus == S_IDLE ||
+            pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                 pDcChargingInfo->IsAvailable == YES) ||
                 (pGunIndexInfo->AcGunIndex > 0 &&
                  pAcChargingInfo->SystemStatus == S_IDLE &&
@@ -229,7 +230,7 @@ static void UserScanFunction(void)
             strcpy((char *)pSysConfig->UserId, "");
         } else if ((pGunIndexInfo->AcGunIndex > 0 &&
                     pSysInfo->CurGunSelectedByAc == DEFAULT_AC_INDEX) ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+                   pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) {
             log_info("// LCM => Authorizing");
 
             setSelGunWaitToAuthor(pSysInfo->CurGunSelected);
@@ -266,6 +267,7 @@ void ScannerCardProcess(void)
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
     SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
 
     if (!isDetectPlugin() &&
             !isCardScan &&
@@ -299,6 +301,7 @@ void ScannerCardProcess(void)
                     // LCM => Authorize fail
                     pSysInfo->SystemPage = _LCM_AUTHORIZ_FAIL;
                     strcpy((char *)pSysConfig->UserId, "");
+                    ShmDcCommonData->AuthroizeType = IdTokenType_Central;
                 }
 
             } ClearAuthorizedFlag();
@@ -364,9 +367,10 @@ void CreateRfidFork(void)
         int fd = -1;
         int isContinue = 1;
         RFID rfid = {0};
+        int module_type = MODULE_EWT;
         fd = InitialRfidPort();
         struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-
+        ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
         //log_info("RFID fork Child's PID is %d", getpid());
 
         while (isContinue) {
@@ -378,7 +382,7 @@ void CreateRfidFork(void)
                 continue;
             }
 
-            if (getRequestCardSN(fd, 0, &rfid) == false) {
+            if (getRequestCardSN(fd, module_type, &rfid) == false) {
                 continue;
             }
 
@@ -455,6 +459,16 @@ void CreateRfidFork(void)
                 }
             }
             log_info("card number = %s", pSysConfig->UserId);
+            if (strlen((char*)pSysConfig->UserId) != 0) {
+                ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
+            }
+            if (rfid.cardType == ISO14443A) {
+                sethaltCard(fd, module_type);
+            } else if (rfid.cardType == IS014443B) {
+
+            } else if (rfid.cardType == FELICA) {
+
+            }
         }
     }
 }

+ 162 - 248
EVSE/Projects/DD360/Apps/CSU/main.c

@@ -61,6 +61,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
 
 static struct ChargingInfoData *pDcChargingInfo = NULL;
@@ -82,8 +83,8 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.20.00.0000.00"; // "V0.16.00.0000.00";
-char* DebugVersion = "v1.20.0";
+char *fwVersion = "V1.21.00.0000.00"; // "V0.16.00.0000.00";
+char* DebugVersion = "v1.21.5";
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -199,7 +200,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(LEFT_GUN_NUM);
@@ -218,7 +221,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(RIGHT_GUN_NUM);
@@ -233,6 +238,7 @@ void destroySelGun(uint8_t curGun)
             ShmSelectGunInfo->PricesInfo[curGun].Balance = FAIL_BALANCE_PRICES;
         }
     }
+
 }
 
 static int waitRightGunPlugIt(uint8_t curGun)
@@ -398,52 +404,105 @@ static void checkGunOTPState(uint8_t gunIndex)
     //log_info("OTP:%d OTPR%d",pSysInfo->OTPTemp,pSysInfo->OTPTempR);
     //水冷機溫度檢測
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
-        if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
-            if (pDcChargingInfo->ChillerTemp >= pSysInfo->OTPTemp ) {
-                if (((gunIndex == 0) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                         ||
-                    ((gunIndex == 1) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-                   ) {
-                    RecordAlarmCode(gunIndex, "012323");
+        if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
+            // 單水冷機
+            // Chiller OTP
+            if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
-                }
-                else
-                {
+                    RecordAlarmCode(gunIndex, "012323");
+                } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
                 }
-            } else if (pDcChargingInfo->ChillerTemp != 0 &&
-                       pDcChargingInfo->ChillerTemp < pSysInfo->OTPTempR) {
-                //ResetChargerAlarmCode(gunIndex, "012323");
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-        } else {
-            // 沒接上 Sensor or 異常
-            //RecordAlarmCode(gunIndex, "011038");
-            //ResetChargerAlarmCode(gunIndex, "012323");
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-            if (((gunIndex == 0) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                     ||
-                ((gunIndex == 1) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-               ) {
+            // Chiller Tube OTP
+            if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-            }
-            else
-            {
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                    RecordAlarmCode(gunIndex, "012332");
+                } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[3] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                }
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
+        } else {
+            // 雙水冷機
+            if (gunIndex == LEFT_GUN_NUM) {
+                if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+                    } else if (ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            } else {
+                if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            }
         }
 
-        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
-        {
+        if (pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES) {
             RecordAlarmCode(gunIndex, "011037");
         }
     }
@@ -466,6 +525,15 @@ static void checkGunOTPState(uint8_t gunIndex)
             //ResetChargerAlarmCode(gunIndex, "012229");
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
+            if  ((gunIndex == 0) &&
+                    (strncmp((char *)&pSysConfig->ModelName[7], "J", 1) == 0)) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            } else if ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "J", 1) == 0) )) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            }
         }
         break;
 
@@ -1539,11 +1607,7 @@ uint8_t isPrechargeStatus_ccs(uint8_t gunIndex)
     uint8_t result = 0x00;
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
-        result = ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;
-    }
-
-    return result;
+    return ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;;
 }
 
 bool isEvStopCharging_ccs(uint8_t gunIndex)
@@ -1643,7 +1707,7 @@ void _DetectPlugInTimeout(void)
 	//pSysInfo->SystemPage = _LCM_COMPLETE;
 	setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING);
 #elif DD360 || DD360Combox
- 	setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE);
+ 	setChargerMode(pSysInfo->CurGunSelected, S_IDLE);
 #endif
     systemPageRestoreInit();
 }
@@ -3801,6 +3865,7 @@ static void autoStartCharging(uint8_t gunIndex)
                     ChangeGunSelectByIndex(gunIndex);
                     confirmSelGun(gunIndex);
                     pDcChargingInfo->isEVCCIDVerify = true;
+                    ShmDcCommonData->AuthroizeType = IdTokenType_MacAddress;
                     pSysInfo->SystemPage = _LCM_AUTHORIZING;
                 }
             } else
@@ -3811,6 +3876,7 @@ static void autoStartCharging(uint8_t gunIndex)
             ChangeGunSelectByIndex(gunIndex);
             confirmSelGun(gunIndex);
             pSysInfo->SystemPage = _LCM_AUTHORIZING;
+            ShmDcCommonData->AuthroizeType = IdTokenType_NoAuthorization;
         }
         if (strcmp( (char *)pSysConfig->UserId , OldUseId ) != EQUAL) {
             strcpy((char *)OldUseId, (char *)pSysConfig->UserId);
@@ -4111,9 +4177,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_Chademo:
         // 檢查樁端的 GFD 結果
         if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_chademo(gunIndex) > 6 &&
-                isPrechargeStatus_chademo(gunIndex) < 8
-           ) {
+                isPrechargeStatus_chademo(gunIndex) >= 6) {
             // 當前操作的槍號,進入 Charging
             setChargerMode(gunIndex, MODE_CHARGING);
         }
@@ -4160,8 +4224,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_GB:
         // 檢查樁端的 GFD 結果
         //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-        if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_gb(gunIndex) > 6) {
+        if (sysStatus == S_PREPARING_FOR_EVSE && isPrechargeStatus_gb(gunIndex) >= 6) {
             setChargerMode(gunIndex, MODE_CHARGING);
         }
 
@@ -4353,6 +4416,7 @@ int main(void)
     ShmRelayModuleData = (struct RelayModuleData *)GetShmRelayModuleData();
     ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
     ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
+    ShmOCPP20Data = (struct OCPP20Data*)GetShmOCPP20Data();
     ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
 	
@@ -4454,6 +4518,9 @@ int main(void)
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
 
             pDcChargingInfo->IsAvailable = DB_Get_Operactive(_index);
+            if (!DB_Get_PowerConsumption(_index)) {
+                DB_Insert_PowerConsumption(_index, 0);
+            }
         }
         DB_Reboot_Record();
     }
@@ -4484,6 +4551,9 @@ int main(void)
 
     pSysInfo->OTPTemp = GUN_OTP_VALUE;
     pSysInfo->OTPTempR = GUN_OTP_RECOVERY;
+
+    time_t ShowEVStatusTimer[2] = { 0 };
+
     for (;;) {
 
         CheckOcppStatus();
@@ -4582,14 +4652,16 @@ int main(void)
                 CheckSmartChargeProfile(gunIndex);
             }
 
-            //log_info("index = %d, ErrorCode = %s",
-            //         gunIndex,
-            //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-
+            case S_RESERVATION:
                 if (isModeChange(gunIndex)) {
-                    log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    if (pDcChargingInfo->SystemStatus == S_IDLE)
+                        log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                        log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
+                        ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
+                    }
                     pDcChargingInfo->PresentChargedDuration = 0;
                     pDcChargingInfo->RemainChargingDuration = 0;
                     pDcChargingInfo->PresentChargingVoltage = 0;//DS60-120 add
@@ -4598,9 +4670,11 @@ int main(void)
                     strcpy((char *)pDcChargingInfo->StopDateTime, "");
                     strcpy((char *)pDcChargingInfo->StartUserId, "");
                     strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "");
-
+                    
                     //Jerry add
                     memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo));
+                    memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo));
+                    DB_Get_PowerConsumption(gunIndex);
                     ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES;
                     destroySelGun(gunIndex);
                     ResetDetAlarmStatus(gunIndex); //recovery OVP status code
@@ -4611,12 +4685,6 @@ int main(void)
                     ReleaseAlarmCode(gunIndex);
                 }
 
-            case S_RESERVATION:
-                if (isModeChange(gunIndex)) {
-                    log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
-                    ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
-                }
-
                 if (pDcChargingInfo->IsAvailable == NO) {
                     setChargerMode(gunIndex, MODE_MAINTAIN);
                 }
@@ -4732,11 +4800,17 @@ int main(void)
                     } else if (pSysInfo->OrderCharging == NO_DEFINE) {
                         if (pDcChargingInfo->ConnectorPlugIn == YES &&
                                 pDcChargingInfo->IsAvailable &&
-                                pDcChargingInfo->SystemStatus == S_IDLE &&
+                                (pDcChargingInfo->SystemStatus == S_IDLE ||
+                                    pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                                 //waitSelectGunPlugIt(gunIndex)
                                 (waitRightGunPlugIt(gunIndex) == PASS ||
-                                 waitLeftGunPlugIt(gunIndex) == PASS)
-                           ) {
+                                 waitLeftGunPlugIt(gunIndex) == PASS) ) {
+                            if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                                if (strcmp((char*)pSysConfig->UserId, (char*)ShmDcCommonData->pGunInfo[gunIndex].ReservationID) != EQUAL) {
+                                    //log_info("Not Resercation ID");
+                                    continue;
+                                }
+                            }
                             log_info("-----------------2----------------- ");
                             ChangeGunSelectByIndex(gunIndex);
                             AddPlugInTimes(gunIndex);
@@ -4745,6 +4819,7 @@ int main(void)
                                      gunIndex,
                                      pDcChargingInfo->StartUserId);
                             strcpy((char *)pSysConfig->UserId, "");
+                            ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
                             // 當前操作的槍號,進入 Preparing
                             setChargerMode(gunIndex, MODE_REASSIGN_CHECK);
                             ClearDetectPluginFlag();
@@ -4758,10 +4833,6 @@ int main(void)
                         // AUDI_LCM_CHANGE
                         pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG;
                     }
-                } else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
-                    if (!isReservationExpired(gunIndex)) {
-                        pDcChargingInfo->SystemStatus = S_IDLE;
-                    }
                 } /*else if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE &&
                            (pDcChargingInfo->ConnectorPlugIn == YES &&
                             pDcChargingInfo->IsAvailable)
@@ -4775,7 +4846,8 @@ int main(void)
                         ClearDetectPluginFlag();
                         continue;
                     }
-                } */else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
+                } */
+                else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
                         pSysInfo->CurGunSelected == gunIndex && !pDcChargingInfo->isEVCCIDVerify) {
                     systemPageRestoreInit();
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
@@ -4860,7 +4932,7 @@ int main(void)
 
                 if (ShmPsuData->SystemPresentPsuQuantity > 0 &&
                         ShmPsuData->SystemAvailablePower > 10 &&
-                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 5000000) {
+                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 1000000) {
                     setChargerMode(gunIndex, MODE_PREPARE_FOR_EV);
                 }
 
@@ -4931,52 +5003,7 @@ int main(void)
                 }
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 檢查樁端的 GFD 結果
-                    if (isPrechargeStatus_chademo(gunIndex) > 5 &&
-                            isPrechargeStatus_chademo(gunIndex) < 8) {
-                        // 當前操作的槍號,進入 Charging
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    // 檢查樁端的 GFD 結果
-                    //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-                    if (isPrechargeStatus_gb(gunIndex) > 9) {
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
 
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 檢查樁端的 GFD 結果
-                    if ((pDcChargingInfo->GroundFaultStatus == GFD_PASS ||
-                            pDcChargingInfo->GroundFaultStatus == GFD_WARNING)) {
-                        setChargerMode(gunIndex, MODE_CCS_PRECHARGE_STEP0);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-                }
-#endif //0
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
 
                 // LCM => Pre-charging
@@ -5003,64 +5030,12 @@ int main(void)
                 pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]);
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012289");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    }
-                    //else if (isPrechargeStatus_gb(gunIndex) == 10 &&
-                    //           (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //             pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //            (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //             pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL))
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012290");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012288");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
+
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime) >= 5) {
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
-#endif //0
 
                 if ((evBoardStopState = isEvBoardStopChargeFlag(gunIndex)) > 0) {
                     // 板端要求停止 (錯誤)
@@ -5122,86 +5097,21 @@ int main(void)
 
                     //log_info ("terminating......................... %x ", gunIndex);
                     StopGunInfoTimeoutDet(gunIndex);
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
 
                 //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-
-                    //if (isEvStopCharging_chademo(gunIndex) == YES ||
-                    //        isPrechargeStatus_chademo(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //log_info("************ GB lock Status = %d, status = %d ",
-                    //         isEvStopCharging_gb(gunIndex),
-                    //         isPrechargeStatus_gb(gunIndex));
-
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
 
-                    //if (isEvStopCharging_gb(gunIndex) == YES ||
-                    //        isPrechargeStatus_gb(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-
-                    //if (isEvStopCharging_ccs(gunIndex) == YES &&
-                    //        (isPrechargeStatus_ccs(gunIndex) >= 53 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 0  ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 13 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 14)) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                }
-#endif //0
                 if (pDcChargingInfo->SystemStatus == S_ALARM) {
                     if (pDcChargingInfo->ConnectorPlugIn == NO &&
                             GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                        setChargerMode(gunIndex, MODE_IDLE);
+                        if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                            setChargerMode(gunIndex, MODE_RESERVATION);
+                        } else {
+                            setChargerMode(gunIndex, MODE_IDLE);
+                        }
                     }
                 } else {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
@@ -5244,9 +5154,13 @@ int main(void)
 
                 if (pDcChargingInfo->ConnectorPlugIn == NO &&
                         GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                    setChargerMode(gunIndex, MODE_IDLE);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                        setChargerMode(gunIndex, MODE_RESERVATION);
+                    } else {
+                        setChargerMode(gunIndex, MODE_IDLE);
+                    }
                     destroySelGun(gunIndex); //Jerry add
-#ifdef defined DD360 || defined DD3660ComBox
+#if defined DD360 || defined DD3660ComBox
 					//pSysInfo->SystemPage = _LCM_IDLE;
                     connectorPageRestoreIdle();
 #endif

+ 112 - 6
EVSE/Projects/DD360/Apps/Config.h

@@ -135,11 +135,17 @@ enum _GUN_TYPE {
     _Type_GB,
     _Type_AC,
 };
-
+enum _CCS_GUN_TYPE {
+    _TYPE_CCS_NONE  = 0,
+    _TYPE_CCS1_Natural,
+    _TYPE_CCS1_Liquid,
+    _TYPE_CCS2_Natural,
+    _TYPE_CCS2_Liquid,
+};
 enum _LCM_INDEX {
-    _LCM_INIT          = 0x00,
-    _LCM_IDLE          = 0x01,
-    _LCM_AUTHORIZING   = 0x02,
+    _LCM_INIT = 0x00,
+    _LCM_IDLE = 0x01,
+    _LCM_AUTHORIZING = 0x02,
     _LCM_AUTHORIZ_COMP = 0x03,
     _LCM_AUTHORIZ_FAIL = 0x04,
     _LCM_WAIT_FOR_PLUG = 0x05,
@@ -147,9 +153,13 @@ enum _LCM_INDEX {
     _LCM_CHARGING      = 0x07,
     _LCM_COMPLETE      = 0x08,
     _LCM_FIX           = 0x09,
+#ifdef DD360Audi
     _LCM_SELECT_GUN    = 0x0A,
     _LCM_EMERGENCY     = 0x0B,
     _LCM_DISCONNECT    = 0x0C,
+#else
+    _LCM_EMERGENCY     = 0x0A,
+#endif
     _LCM_NONE          = 0xFF,
 };
 
@@ -267,7 +277,22 @@ enum _CCS_TYPE {
     _CCS_TYPE_CCS1 = 0,
     _CCS_TYPE_CCS2 = 1,
 };
-
+enum _WEATHER_TYPE {
+	_WEATHER_TYPE_SUN = 1,
+	_WEATHER_TYPE_CLOUDY,
+	_WEATHER_TYPE_RAIN,
+	_WEATHER_TYPE_THUNDER,
+	_WEATHER_TYPE_SNOW,
+	_WEATHER_TYPE_FOG,
+};
+enum _CREDITCARD_STATUS {
+	_CREDITCARD_IDLE,
+	_CREDITCARD_PREAUTH,
+	_CREDITCARD_PREAUTHCOMPLETE,
+	_CREDITCARD_CANCEL,
+	_CREDITCARD_SETTLEMENT,
+	_CREDITCARD_START,
+};
 //------------------------------------------------------------------------------
 //struct StructMeter {
 //    float curMeterValue;
@@ -347,7 +372,8 @@ typedef union {
     struct {
         uint8_t ChillerOTP: 1;            //chiller Temperature OVP
         uint8_t ChillerTempSensorFail: 1; //Chiller temperature sensor failure
-        uint8_t Reserved: 6;
+        uint8_t ChillerTubeOTP : 1;
+        uint8_t Reserved: 5;
     } StatusBit;
 } ChillerTempErr;
 
@@ -363,6 +389,75 @@ typedef struct StPcPsuOutput { //from power cabinet PSU output
     uint16_t Current;
 } PcPsuOutput;
 
+typedef struct StPowerConsumptionInfo {
+    float Gun1_Consumption;
+    float Gun2_Consumption;
+    float Gun3_Consumption;
+    float Gun4_Consumption;
+} PowerConsumptionValue;
+
+typedef struct StPowConsumValue {
+    uint32_t Gun1_Consumption;
+    uint32_t Gun2_Consumption;
+    uint32_t Gun3_Consumption;
+    uint32_t Gun4_Consumption;
+} PowConsumValue;
+
+typedef struct StGunInfo {
+    int ConnectorID;
+    char ReceiptInfo[255];
+    int finalcost_flag;
+    time_t EVLoseTimer;
+    uint8_t EVLoseFlag;
+    char ReservationID[32];
+    uint8_t ReservationStatus;
+    char UserPriceString[255];
+    float PowerConsumption;
+    time_t RecordEnergyTime;
+    char ChargeStartTime[32];
+    char ChargeStopTime[32];
+    char ChargeDuration[32];
+    uint8_t withChiller;      //是否有水冷機
+} GunInfo;
+
+typedef struct Psu_VersionInfo{
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PsuVerInfo;
+
+enum _LCM_UPGRADE_RESULT {
+    _LCM_UPGRADE_RESULT_WAIT = 0,
+    _LCM_UPGRADE_RESULT_PASS,
+    _LCM_UPGRADE_RESULT_FAIL,
+};
+
+typedef struct stTransInfo
+{
+	unsigned char TransDate[6];	//交易日期
+	unsigned char TransTime[6];	//交易時間
+	unsigned char ROC[12];		//EDC簽單調閱編號 (左靠右補空白)
+	unsigned char ApprovalNo[9];		//授權碼[信用卡退貨交易] (左靠右補空白)
+	unsigned char StoreId[18];		//櫃號,機號,發票號碼(左靠右補空白)
+	unsigned char RRN[12];		//信用卡交易序號
+	unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+	unsigned char TransAmount[12];		//交易金額
+	unsigned char VemData[64];		//無人自助設備交易資訊 交易別31/32 (預授權完成/預授權取消) 必要欄位 資訊來源為交易別13 (預授權)的回傳
+}TransInfo;
+
+typedef struct stRecordTransactionInfo
+{
+	int TransactionId;
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    unsigned char ApprovalNo[9];
+    unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+    unsigned char VemData[64];
+    float Amount;
+    unsigned char IsUpload; // 0: not upload, 1: uploaded
+    unsigned char res;
+}RecordTransactionInfo;
+
 typedef struct StDcCommonInfo {
     uint8_t RebootCount;
     uint8_t CcsVersion;
@@ -382,6 +477,17 @@ typedef struct StDcCommonInfo {
     uint8_t chillerCtrl;
     uint8_t debugflag;
     uint8_t LcmFwVersion;
+    int TZOffset;
+    uint8_t AuthroizeType; // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
+    char QRCodeString[255];
+    char DefaultPriceString[255];
+    PowerConsumptionValue pConsumption;
+    int WeatherID;
+    float Temperature;
+    int Location;
+    GunInfo pGunInfo[2];
+    uint8_t showNetPackage;
+    uint8_t showCanPackage;
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 113 - 1
EVSE/Projects/DD360/Apps/DataBase/DataBase.c

@@ -14,7 +14,7 @@
 
 //------------------------------------------------------------------------------
 static sqlite3 *localDb;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 //===============================================
 // SQLite3 related routine
@@ -59,6 +59,11 @@ int DB_Open(void)
                             "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, "
                             "`rebootDatetime` TEXT NOT NULL, unique(rebootDatetime) on conflict replace);";
 
+    char *createPowerConsumption = "CREATE TABLE IF NOT EXISTS power_consumption( "
+                         "idx INTEGER PRIMARY KEY AUTOINCREMENT, "
+                         "connector TEXT, "
+                         "val TEXT);";
+
     if (sqlite3_open(DB_FILE, &localDb)) {
         result = FAIL;
         log_info( "Can't open database: %s", sqlite3_errmsg(localDb));
@@ -88,6 +93,14 @@ int DB_Open(void)
             log_info( "Opened local record table successfully");
         }
 
+        //DS60-120
+        if (sqlite3_exec(localDb, createPowerConsumption, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Create power consumption record table error message: %s", errMsg);
+        } else {
+            log_info("Opened power consumption record table successfully");
+        }
+
         if (sqlite3_exec(localDb, createrebootSql, 0, 0, &errMsg) != SQLITE_OK) {
             result = FAIL;
             log_info( "Create reboot record table error message: %s", errMsg);
@@ -99,6 +112,7 @@ int DB_Open(void)
         sqlite3_close(localDb);
     }
 
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     return result;
 }
 
@@ -222,6 +236,104 @@ int DB_Get_Operactive(uint8_t gunIndex)
     return result;
 }
 
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully (%f).", energy);
+        sprintf(sqlStr,"insert into power_consumption (connector, val) values (%d, %f);",
+            gunIndex,
+            energy); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Insert power consumption error message: %s", errMsg);
+        } else {
+            log_info("Insert connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully.");
+        sprintf(sqlStr,"update power_consumption set val = %f where connector = %d; ",
+                        energy,
+                        gunIndex); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("update config error message: %s", errMsg);
+        } else {
+            //log_info("update connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Get_PowerConsumption(uint8_t gunIndex)
+{
+    uint8_t result = true;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    char** rs;
+    int  rows, cols;
+
+    //sprintf(sqlStr, "select * from config where IsAvailable='IsAvailable' and connector=%d;", gunIndex);
+    sprintf(sqlStr, "select * from power_consumption where connector=%d;", gunIndex); //DS60-120 add
+    //DEBUG_INFO("sqlStr= %s", sqlStr);
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        log_info("Local config query database open successfully.");
+        sqlite3_get_table(localDb, sqlStr, &rs, &rows, &cols, &errMsg);
+        if (rows > 0) {
+            for (int idxRow = 1; idxRow <= rows; idxRow++) {
+                ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = atof(rs[(idxRow * cols) + 2]);
+                log_info("Query connector-%d PowerConsumption: %s", gunIndex, rs[(idxRow * cols) + 2]);
+                
+            }
+        } else {
+            log_info("Query connector-%d fail, set default value to operactive.", gunIndex);
+            result = false;
+        }
+
+        sqlite3_free_table(rs);
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+
 int DB_Reboot_Record(void)
 {
     int result = PASS;

+ 3 - 1
EVSE/Projects/DD360/Apps/DataBase/DataBase.h

@@ -10,5 +10,7 @@ int DB_Reboot_Record(void);
 //for Module_EventLog
 int CreateEventRecord(void);
 int InsertEventRecord(uint8_t *statusCode);
-
+int DB_Get_PowerConsumption(uint8_t gunIndex);
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy);
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy);
 #endif /* _DATA_BASE_H_ */

+ 5 - 5
EVSE/Projects/DD360/Apps/Define/define.c

@@ -236,11 +236,11 @@ char AlarmStatusCode[160][6]=
 "012324", // Connector 1 detects abnormal voltage on the output line
 "012325", // Connector 2 detects abnormal voltage on the output line
 "012326", // System task is lost
-"012327", // DC input ovp
+"012327",   // DC input ovp
 "012328",   // DC input uvp
-"012329",   // reserved
-"012330",   // reserved
-"012331",   // reserved
+"012329",   // Psu Can Communication Fault
+"012330",   // Psu Dc to Dc OTP
+"012331",   // Psu Dc to Dc OVP
 "012332",   // reserved
 "012333",   // reserved
 "012334",   // reserved
@@ -255,7 +255,7 @@ char AlarmStatusCode[160][6]=
 "012343",   // reserved
 "012344",   // AC: Meter IC communication timeout
 "012345",   // AC: Pilot negative error
-"012346",   // reserved
+"012346",   // Psu Communication error with CSU
 "012347",   // reserved
 "012348",   // reserved
 "012349",   // reserved

+ 110 - 65
EVSE/Projects/DD360/Apps/Define/define.h

@@ -186,6 +186,8 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 #define ShmLedBdKey				1011
 #define ShmOcpp20ModuleKey		1012
 #define ShmRelay2BdKey			1013
+#define ShmYesCustomKey         1014
+#define ShmOcppPHModuleKey      1015
 
 #define FaultCodeLength         5
 #define AlarmCodeLength         20
@@ -321,8 +323,15 @@ enum CoreProfile {
      TimeOffsetNextTransition,
      SystemUptimeSec,
      FreeVend,
+     FreeVendIdtag,
      OcppServer,
      MaintainServer,
+     StatusNotificationPeriodically,
+     StatusNotificationInterval,
+     PreAuthAmount,
+     isEnableLocalPowerSharing,
+     PowerSharingServerIP,
+     EVCCID_PREFIX,
      ConfigurationVersion,
 	 _CoreProfile_CNT
 };
@@ -336,10 +345,11 @@ enum OCPP_START_ID_TYPE {
     IdTokenType_Central=0,
     IdTokenType_eMAID,
     IdTokenType_ISO14443,
+    IdTokenType_ISO15693,
     IdTokenType_KeyCode,
     IdTokenType_Local,
-    IdTokenType_NoAuthorization,
-    IdTokenType_ISO15693
+    IdTokenType_MacAddress,
+    IdTokenType_NoAuthorization
 };
 /**************************************************************************************/
 /****structure SysConfigData => shall store the data to NAND flash****************/
@@ -414,8 +424,16 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_NOUSE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct LCD_OVERRIDE
 {
+    unsigned char           connectorId;                // LCD override connector id
     unsigned char           page_index;                 // LCD override page index
     unsigned char           duration;                   // LCD override duration
     unsigned char           isOverideReq:1;             // LCD override request
@@ -448,7 +466,7 @@ struct TTIA
 
 struct LocalSharingInfo
 {
-    unsigned short      AvailableShargingCurrent;       // 0 ~ rating value amp,  Synchronize from local sharing server
+    unsigned short      AvailableShargingCurrent[4];    // 0 ~ rating value amp,  Synchronize from local sharing server
     unsigned char       isConnectedSharingServer:1;     // 0: Disconnected, 1: Connected
 };
 
@@ -464,7 +482,9 @@ typedef union
         unsigned int HardResetStop:1;               // 0: no effect,    1: hard reset stop
         unsigned int SoftResetStop:1;               // 0: no effect,    1: soft reset stop
         unsigned int InvalidIdStop:1;               // 0: no effect,    1: invalid stop when StopTransactionOnInvalidId is true
-        unsigned int res:25;
+        unsigned int RemoteStop:1;                  // 0: no effect,    1: remote stop
+        unsigned int UnlockStop:1;                  // 0: no effect,    1: unlock stop
+        unsigned int res:23;
     }bits;
 }ChargingStop;
 
@@ -557,9 +577,9 @@ struct SysConfigData
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
-	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
+	unsigned char           isEnableLocalPowerSharing;  //0: Disable power sharing  1: Master   2: Slave
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
-    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
+    struct LCD_NOUSE        Legacy_LcdOveride;          // LCD override info (no use anymore)
     struct TTIA             TTIA_Info;                  // TTIA configuration struct
 
     /************PowerCabinet************/
@@ -570,6 +590,7 @@ struct SysConfigData
     unsigned char           MaintainServerURL[512];             // ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
     unsigned char           MaintainServerSecurityProfile;      // Maintain server security profile 0~3
     unsigned char           MaintainServerSecurityPassword[41]; // Maintain server AuthorizationKey for security profile
+    unsigned char           PowerSharingServerIP[512];          // Local power sharing server ip address
 };
 
 struct ChargingInfoData
@@ -609,7 +630,7 @@ struct ChargingInfoData
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
 	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
-	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MaxAddress   7: NoAuthorization
+	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
@@ -685,7 +706,7 @@ typedef struct
     unsigned char       AuthType;                       // 0: _AuthType_None,   1: _AuthType_RFID, 2: _AuthType_RemoteStart
     unsigned char       AuthResult;                     // 0: _AuthResult_None, 1: _AuthResult_Valid,   2: _AuthResult_Invalid
     unsigned char       AuthRequest;                    // 0: no request, 1: authorize request
-    unsigned char       res;
+    unsigned char       AuthIdType;
 }AuthorizingInfoData;
 
 typedef union
@@ -699,26 +720,12 @@ typedef union
         unsigned int MiscNeedAnnouncement:1;            // 0: no need,      1: need send misc command
         unsigned int NeedDispenserVerInfo:1;            // 0: no need,      1: need dispenser to report it's version info
         unsigned int AuthorizeRequest:1;                // 0: idle,         1: requesting                           ( dispenser -> cabinet)
-        unsigned int ConnectorTimeoutConfigRequest:1;   // 0: no request,   1: connector timeout setting            (    ocpp   -> cabinet -> dispenser)
-        unsigned int DefaultPriceConfigRequest:1;       // 0: no request,   1: default price setting                (    ocpp   -> cabinet -> dispenser)
-        unsigned int CurrencyConfigRequest:1;           // 0: no request,   1: currency setting                     (    ocpp   -> cabinet -> dispenser)
-        unsigned int HardwareRebootRequest:1;           // 0: no request,   1: hardware reboot request              (    ocpp   -> cabinet -> dispenser)
         unsigned int HardwareRebootConfirm:1;           // 0: no effect,    1: dispenser confirmed
-        unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
         unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
         unsigned int FirmwareUpdateRequest:1;           // firmware update request
         unsigned int FirmwareUpdateConfirm:1;           // firmware update start
         unsigned int FirmwareUpdateCompleted:1;         // firmware update completed
-        unsigned int BackendStatusRequest:1;            // 0: no request,   1: backend connection status has changed            ( cabinet -> dispenser)
-        unsigned int EthernetStatusRequest:1;           // 0: no request,   1: ethernet connection status has changed           ( cabinet -> dispenser)
-        unsigned int WiFiStatusRequest:1;               // 0: no request,   1: wifi connection status has changed               ( cabinet -> dispenser)
-        unsigned int TelcomModemStatusRequest:1;        // 0: no request,   1: 4g connection status has changed                 ( cabinet -> dispenser)
-        unsigned int BillingStatusRequest:1;            // 0: no request,   1: billing status has changed                       ( cabinet -> dispenser)
-        unsigned int StopButtonStatusRequest:1;         // 0: no request,   1: stop charging button status has changed          ( cabinet -> dispenser)
-        unsigned int AuthModeConfigRequest:1;           // 0: no request,   1: AuthMode Config has changed                      ( cabinet -> dispenser)
-        unsigned int EVCCIDConfigRequest:1;             // 0: no request,   1: EVCCID Config has changed                        ( cabinet -> dispenser)
-        unsigned int LEDIntensityRequest:1;             // 0: no request,   1: LED Intensity has changed                        ( cabinet -> dispenser)
-        unsigned int res:7;
+        unsigned int res:21;
     }bits;
 }DispenserSettingFlag;
 
@@ -735,7 +742,7 @@ struct DispenserModule
     unsigned char   RfidCardNumEndian;          //0: little endian,  1: big endian
     unsigned char   isAPP;                      //for AuthorisationMode=0; 0:false, 1:true
     unsigned char   isQRCode;                   //for AuthorisationMode=0; 0:false, 1:true
-    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true
+    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true; for Noodoe Credit Card +2^1:true
     unsigned char   QRCodeMadeMode;             //for isQRCode=1 ; 0: default	1:customized
     unsigned char   QRCodeContent[128];         //for QRCodeMadeMode=1
 
@@ -794,10 +801,6 @@ struct DispenserInfoData
     }CheckInLog;                                                        // record dispenser checkin status
     unsigned char               ConnectorLog[GENERAL_GUN_QUANTITY];     // record connector quantity of dispenser
     struct ConnectionInfoData   ConnectionInfo[GENERAL_GUN_QUANTITY];
-
-    unsigned short      ConnectorTimeout;           // connector plug in timeout, unit 1s
-    unsigned int        DefaultPrice;               // dispenser default price, unit: 0.01 (dollar/kWh)
-    unsigned char       Currency;                   // dispenser currency index
 };
 
 struct WARNING_CODE_INFO
@@ -815,16 +818,11 @@ typedef union
     struct
     {
         unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging                   ( dispenser -> cabinet)
-        unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStartConfirm:1;
-        unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStopConfirm:1;
-        unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  UnlockStopConfirm:1;
         unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop                           ( dispenser -> cabinet)
         unsigned int  PsuReleasable:1;
-        unsigned int  AvailabilityRequest:1;            // 0: no request,    1: change availability                             (    ocpp   -> cabinet -> dispenser)
-        unsigned int  AccountBalanceRequest:1;          // 0: no request,    1: set account balance                             (    ocpp   -> cabinet -> dispenser)
         unsigned int  AnnounceBalance:1;                //
         unsigned int  StartWaitPlug:1;                  //
         unsigned int  NeedCleanAuthorizeInfo:1;         //
@@ -837,7 +835,7 @@ typedef union
         unsigned int  Disconnection:1;
         unsigned int  GfdDetection:1;                   // 0: stop,         1: start
         unsigned int  GetStartChargingSoc:1;            // 0: no effect,    1: get start soc
-        unsigned int  res:8;
+        unsigned int  res:13;
     }bits;
 }ConnectorParameter;
 
@@ -874,9 +872,12 @@ struct ConnectorInfoData
     float                   CapabilityCurrent;              // unit 0.1A
     float                   CapabilityPower;                // unit 0.1kW
 
-    unsigned int            UserPrice;                      // connector user's user price, unit: 0.01 (dollar / kWh)
-    unsigned int            TotalCost;                      // connector user's total cost, unit: 0.01 dollar
-    int                     AccountBalance;                 // connector user's account balance, unit: 0.01 dollar
+    float                   UserPrice;                      // connector user's user price, unit: 1 (dollar / kWh)
+    float                   TotalCost;                      // connector user's total cost, unit: 1 dollar
+    float                   AccountBalance;                 // connector user's account balance, unit: 1 dollar
+    float                   CostDiscount;                   // connector user's Discount or couponPoint, unit: 1 point
+    float                   EnergyCost;                     // connector user's energy cost, unit: 1 dollar
+    float                   ParkingFee;                     // connector user's parking fee, unit: 1 dollar
 };
 
 typedef union
@@ -892,23 +893,6 @@ typedef union
     }bits;
 }CabinetSettingFlag;
 
-typedef struct
-{
-    unsigned int ConnectionTimeout;             // unit: 1s
-    unsigned int DefaultPrice;                  // unit: 0.01dollar
-    unsigned int Currency;                      // currency index
-    unsigned int BackendStatus;                 // 0: disable, 1: connected, 2: disconnected
-    unsigned int EthernetStatus;                // 0: disable, 1: connected, 2: disconnected
-    unsigned int WiFiStatus;                    // 0: disable, 1: connected, 2: disconnected
-    unsigned int TelcomModemStatus;             // 0: disable, 1: connected, 2: disconnected
-    unsigned int BillingStatus;                 // 0: disable, 1: enable
-    unsigned int StopChargingButton;            // 0: disable, 1: enable
-    unsigned int HardwareReboot;                // 1: HardwareReboot, Other value: no effect
-    unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
-    unsigned int AuthModeConfig;                // 0: enable,  1: disable
-    unsigned int EVCCIDConfig;                  // 0: disable, 1: enable
-}CabinetMiscCommand;
-
 typedef struct DC_METER_INFO
 {
     double presetVoltage;                       // resolution: 1.000v
@@ -1011,11 +995,11 @@ struct SysInfoData
     unsigned char           AuthorizedType;             // record authorized type
     unsigned char           AuthorizedStatus;           // cabinet authorized status
     CabinetSettingFlag      CabinetSetting;
-    CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
     DC_Meter_Info DcMeterInfo[4];
     unsigned char           OTPTemp;                    // OTP Temperature
     unsigned char           OTPTempR;                   // OTP Recovery Temperature
+    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info (no use anymore)
 };
 
 struct SysConfigAndInfo
@@ -1334,9 +1318,9 @@ char AlarmStatusCode[160][6]=
     "012326",   // System task is lost
     "012327",   // DC input ovp
     "012328",   // DC input uvp
-    "012329",   // reserved
-    "012330",   // reserved
-    "012331",   // reserved
+    "012329",   // Psu Can Communication Fault
+    "012330",   // Psu Dc to Dc OTP
+    "012331",   // Psu Dc to Dc OVP
     "012332",   // reserved
     "012333",   // reserved
     "012334",   // reserved
@@ -1351,7 +1335,7 @@ char AlarmStatusCode[160][6]=
     "012343",   // reserved
     "012344",   // AC: Meter IC communication timeout
     "012345",   // AC: Pilot negative error
-    "012346",   // reserved
+    "012346",   // Psu Communication error with CSU
     "012347",   // reserved
     "012348",   // reserved
     "012349",   // reserved
@@ -1521,13 +1505,17 @@ struct AlarmCodeData
             unsigned char DcInputOVP:1;                             //bit 7
             //AlarmVal[16]
             unsigned char DcInputUVP:1;                             //bit 0
-            unsigned char :7;                                       //reserved bit 1 ~ bit 7
+            unsigned char PsuCanCommFault:1;                        //bit 1
+            unsigned char PsuDcDcOtp:1;                             //bit 2
+            unsigned char PsuDcDcOvp:1;                             //bit 3
+            unsigned char :4;                                       //reserved bit 4 ~ bit 7
             //AlarmVal[17]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
             //AlarmVal[18]
             unsigned char MeterIcCommTimeout:1;                     //bit 0
             unsigned char PilotNegativeError:1;                     //bit 1
-            unsigned char :6;                                       //reserved bit 2 ~ bit 7
+            unsigned char PsuComminicationErrWithCSU:1;             //bit 2
+            unsigned char :5;                                       //reserved bit 3 ~ bit 7
             //AlarmVal[19]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
 		}bits;
@@ -2312,6 +2300,7 @@ struct PsuData
 	unsigned char           GroupCount;
 	unsigned char           Work_Step;
 	struct PsuModuleVer     PsuVersion[MAX_PSU_QUANTITY];
+	unsigned char           PsuStopChargeFlag;
 };
 
 /************************************************************************************/
@@ -4429,7 +4418,7 @@ struct OCPP16ConfigurationTable
 struct StrcutSetUserPrice
 {
     unsigned char   idToken[21];
-    unsigned char   price[256];
+    unsigned char   price[1024];
 };
 
 struct ChargingPrice
@@ -4473,13 +4462,13 @@ struct StrcutRunningCost
     struct IdlePrice        idlePrice;              // (optional) Price components while not charging. Optional if no idle fee is charged.
     struct NextPeriod       nextPeriod;             // (optional) Pricing for next period
     struct Triggers         triggerMeterValue;      // (optional) Triggers to request a new meter value. Optional if no idle fee charged.
-    unsigned char           description[256];       // Compatible California pricing V1.0
+    unsigned char           description[1024];      // Compatible California pricing V1.0
 };
 
 struct StrcutFinalCost
 {
     int             txId;
-    unsigned char   description[256];
+    unsigned char   description[1024];
 };
 
 struct StructCost
@@ -4598,6 +4587,58 @@ struct StructSessionTarget
     unsigned short      targetDuration;     // Unit: Minutes    0 is unlimit
 };
 
+//===================================
+// YES custom protocol
+//===================================
+struct StructChargerInfo
+{
+    unsigned char station_name[64];
+};
+
+struct StructWeatherInfo
+{
+    int   weatherId;
+    float temperature;
+};
+
+struct StructCreditDeductResult
+{
+    int txId;
+    unsigned char creditNo[64];
+    unsigned char vemData[80];
+    unsigned char ROC[20];
+    unsigned char RRN[20];
+    unsigned char storeId[20];
+    unsigned char approvalNo[20];
+    double        amount;
+    unsigned char deductResult:1;
+    unsigned char isDonateInvoice:1;
+};
+
+struct StructReaderStatus
+{
+    int readerStatus;
+    unsigned char creditNo[64];
+    unsigned char ReportReaderStatusReq:1;
+};
+
+struct StructTcciCustomData
+{
+    struct StructChargerInfo ChargerInfo;
+    struct StructWeatherInfo WeatherInfo;
+    struct StructCreditDeductResult DeductInfo;
+    struct StructReaderStatus ReaderStatus[CONNECTOR_QUANTITY];
+    unsigned char TriggerReaderReq[3];
+    unsigned char SerialNo[CONNECTOR_QUANTITY][37];
+    unsigned char VEMData[CONNECTOR_QUANTITY][65];
+
+    unsigned char ReportCreditDeductReq:1;
+    unsigned char ChargerInfoReq:1;
+    unsigned char ChargerInfoConf:1;
+    unsigned char WeatherInfoReq:1;
+    unsigned char WeatherInfoConf:1;
+};
+
 struct OCPP16Data
 {
     unsigned char                           OcppServerURL[512];     //http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
@@ -4787,6 +4828,7 @@ struct OCPP16Data
     struct StructSignCertificate                    SignCertificate;
     struct StructSignedFirmwareStatusNotification   SignedFirmwareStatusNotification;
     struct StructSessionTarget                      SessionTarget[CONNECTOR_QUANTITY];
+    struct StructTcciCustomData                     TcciCustomData;
 };
 
 
@@ -4831,6 +4873,7 @@ enum OCPP20CtrlrVariable
 	ChargingStation_SupplyPhases,
 	ChargingStation_SystemUptimeSec,
 	ChargingStation_FreeVend,
+	ChargingStation_FreeVendIdtag,
 	Connector_Available,
 	Connector_ConnectorType,
 	Connector_SupplyPhases,
@@ -4879,6 +4922,8 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_WebSocketPingInterval,
 	OCPPCommCtrlr_ResetRetries,
 	OCPPCommCtrlr_PublicKeyWithSignedMeterValue,
+    OCPPCommCtrlr_StatusNotificationPeriodically,
+    OCPPCommCtrlr_StatusNotificationInterval,
     OCPPCommCtrlr_VariableVersion,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
@@ -5099,7 +5144,7 @@ struct ChargingScheduleType
 
 struct ChargingProfileType
 {
-	unsigned short int id;											// Required. Id of ChargingProfile.
+	int id;											                // Required. Id of ChargingProfile.
 	unsigned short int stackLevel;									// Required. Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
 	unsigned char chargingProfilePurpose[36];						// Required. Defines the purpose of the schedule transferred by this profile
 	unsigned char chargingProfileKind[16];							// Required. Indicates the kind of schedule.

+ 1 - 15
EVSE/Projects/DD360/Apps/Makefile

@@ -113,12 +113,6 @@ CHKSYSTASK_SRC_FILES = $(patsubst %.o, %.c, $(CHKSYSTASK_OBJ_FILES))
 %.o: %.c
 	$(CC) $(CFLAGS) -c $<
 
-#Simulation
-SIMULATION_OBJ_FILES = $(COMMON_OBJ_FILES) simulation.o
-SIMULATION_SRC_FILES = $(patsubst %.o, %.c, $(SIMULATION_OBJ_FILES))
-%.o: %.c
-	$(CC) $(CFLAGS) -c $<
-
 #Event Log
 EVENTLOG_OBJ_FILES = $(COMMON_OBJ_FILES) $(DataBaseLib)/DataBase.o \
 						$(EventLogLib)/Module_EventLogging.o
@@ -148,7 +142,7 @@ all: CopyFile apps
 apps: MainTask DoCommTask EvCommTask UpdateFWTask ChkSysTask \
 		EventLoggingTask InternalCommTask LcmControlTask \
 			PrimaryCommTask ReadCmdlineTask UnsafetyOutputTool \
-				SimulationApp FactoryConfigApp OtherTools CleanExec
+				FactoryConfigApp OtherTools CleanExec
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
@@ -180,11 +174,6 @@ ChkSysTask:
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o Module_ChkSysTask.o $(ChkSysTaskLib)/Module_ChkSysTask.c
 	#$(CC) -o Module_ChkSysTask Module_ChkSysTask.o 
 
-SimulationApp:
-	$(CC) $(DEFINE) $(SIMULATION_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) -o simulation 
-	#$(CC) $(DEFINE) $(CFLAGS) -c -o simulation.o simulation.c
-	#$(CC) -o simulation simulation.o
-
 EventLoggingTask:
 	$(CC) $(DEFINE) $(EVENTLOG_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(Lib_SQLite3) -o Module_EventLogging
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o define.o $(DefineLib)/define.c
@@ -242,7 +231,6 @@ OtherTools:
 	cp -f Module_EvComm $(RootPath)
 	cp -f Module_UpdateFW $(RootPath)
 	cp -f Module_ChkSysTask $(RootPath)
-	cp -f simulation $(RootPath)
 	cp -f Module_EventLogging $(RootPath)
 	cp -f Module_InternalComm $(RootPath)
 	cp -f Module_LcmControl $(RootPath)
@@ -262,7 +250,6 @@ OtherTools:
 	cp -f Module_EvComm $(OutputPath)
 	cp -f Module_UpdateFW $(OutputPath)
 	cp -f Module_ChkSysTask $(OutputPath)
-	cp -f simulation $(OutputPath)
 	cp -f Module_EventLogging $(OutputPath)
 	cp -f Module_InternalComm $(OutputPath)
 	cp -f Module_LcmControl $(OutputPath)
@@ -282,7 +269,6 @@ CleanExec:
 	rm Module_EvComm
 	rm Module_UpdateFW
 	rm Module_ChkSysTask
-	rm simulation 
 	rm Module_EventLogging
 	rm Module_InternalComm
 	rm Module_LcmControl

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 804 - 60
EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.c


+ 120 - 3
EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.h

@@ -16,7 +16,7 @@
 #define TFTP_PULL_CMD                           "tftp"
 #define SIGTERM_MSG                             "SegmentFault.~~~~\n"
 
-#define MAX_REGISTER_NUM                        30
+#define MAX_REGISTER_NUM                        50
 
 #define CHECK_NETWORK_FAIL_COUNT                10//10
 #define CONNECT_SERVER_FAIL_COUNT               3//5
@@ -80,6 +80,25 @@
 #define REG_QRCODE_URL_INFO                     0X10
 #define REG_WAIT_PLUG_IT_STATE                  0x11
 #define REG_Ground_Fault_Detection              0x12
+#define REG_CABINET_DCM_VERSION                 0x13
+#define REG_CABINET_OTHER_VERSION               0x14
+#define REG_TOTAL_PSU_QUANTITY                  0x15
+#define REG_PSU_VERSION                         0x16
+#define REG_RESERVATION_IDTAG                   0x17
+#define REG_DISPENSER_REQUEST                   0x18
+#define REG_REMOTE_START_NO_ID                  0x19
+#define REG_REFUND_AMOUNT                       0x1A
+#define REG_PREPAYMENT_INFO                     0x1B
+#define REG_PAYMENT_FAIL_REASON                 0x1C
+#define REG_CONNECTOR_QR_CODE                   0x1D
+#define REG_STATION_INFO                        0x1E
+#define REG_DEDUCT_INFO                         0x1F
+#define REG_READ_CABINET_SYSTEMID               0x20
+#define REG_READ_DEFAULT_PRICE                  0x21
+#define REG_READ_USER_PRICE                     0x22
+#define REG_RECEIPT_INFO                        0x23
+#define REG_POWER_CONSUMPTION_INFO              0x24
+#define REG_READ_CHARGING_TIMESTAMP             0x25
 
 //------------------------------------------------------------------------------
 //--- dispenser result ---
@@ -111,19 +130,90 @@
 #define MISC_CMD_WEB_STOP_CHARGING              (0x000B)
 #define MISC_CMD_AUTH_DISABLE					(0x000C)
 #define MISC_CMD_EVCCID_ENABLE					(0x000D)
+#define MISC_CMD_LED_INTENSITY                  (0x000E)
+#define MISC_CMD_AC_CONTACTOR                   (0x000F)
+#define MISC_CMD_TIME_OFFSET                    (0x0010)
 
 #define MISC_CMD_HARDWARE_REBOOT                (0x0101)
 #define MISC_CMD_SOFTWARE_RESTART               (0x0102)
 #define MISC_CMD_REMOTE_START_CHARGING          (0x0103)
 #define MISC_CMD_REMOTE_STOP_CHARGING           (0x0104)
 #define MISC_CMD_REMOTE_UNLOCK                  (0x0105)
+#define MISC_CMD_RESERVATION                    (0x0106)
+#define MISC_CMD_CHANGE_LCM_PAGE                (0x0107)
+#define MISC_CMD_QR_CODE_REQ                    (0x0108)
+#define MISC_CMD_STATION_INFO_REQ               (0x0109)
+#define MISC_CMD_FINAL_COST_REQ                 (0x010A)
+#define MISC_CMD_LINE_STATUS_REQ                (0x010B)
+#define MISC_CMD_DEFAULT_PRICE_REQ              (0x010C)
+#define MISC_CMD_USER_PRICE_REQ                 (0x010D)
+#define MISC_CMD_RECEIPT_REQ                    (0x010E)
 
 #define ST_UPDATE_FIRMWARE                      (0x01)
 #define ST_NO_UPDATE_FIRMWARE                   (0x02)
 
+#define LCM_PAGE_REMOTE_START_NO_ID             (0x0001)
+#define DISPENSER_REQ_CHARGING_CANCEL           (0x0001)
+
+#define UPLOAD_DEDUCT_DB						(0x5656)
+
+
 //------------------------------------------------------------------------------
 #pragma pack(push)
 #pragma pack(1)
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ChargingCancel : 1; // 0: no effect, 1: charging cancel request
+        unsigned int res : 31;
+    }bits;
+} ConnectorActReqVar;
+
+typedef struct StDeductInfoVar {
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    int TransactionId;								// transaction id
+    int Amount;                                     // unit = 0.01 dollar
+    char ApprovalNumber[12];						// approval number
+} DeductInfoVar;
+
+/*
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int JoinLine:1;                    // 0: no effect,                1: JoinLine page is trigger
+        unsigned int PaymentSwitch:1;               // 0: no effect,                1: PaymentSwitch page is trigger
+        unsigned int res:30;
+    }bits;
+} ChangePageReq;
+*/
+
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ReservationReq:1;              // 0: no effect,                1: need to request Reservation
+        unsigned int RemoteStartNoID:1;             // 0: no effect,                1: need to request RemoteStartNoID
+        unsigned int StationInfoReq:1;              // 0: no effect,                1: need to request StationInfo
+        unsigned int FinalCostReq:1;                // 0: no effect,                1: need to request FinalCost
+        unsigned int DefaultPriceReq : 1;           // 0: no effect,                1: need to request Default price
+        unsigned int UserPriceReq : 1;              // 0: no effect,                1: need to request User price
+        unsigned int ReceiptReq : 1;                // 0: no effect,                1: need to request Receipt
+        unsigned int res:27;
+    }bits;
+} MoreInfoReq;
+
+typedef struct StStationVar {
+    int StationID;
+    char StationName[64];
+    int WeatherID;
+    float Temperature;
+} StationVar;
 
 typedef struct StConnectorState {
     uint8_t State;
@@ -131,7 +221,8 @@ typedef struct StConnectorState {
     uint8_t ConnectorTemp;
     uint8_t ChillerTemp;
     uint8_t PlugIn;
-    uint8_t Reserved[2];
+    uint32_t consumption;
+    uint8_t Reserved[1];
 } ConnectorState;
 
 typedef struct StConnectorIDTable {
@@ -232,9 +323,35 @@ typedef struct StAccountInfo {
     int UserPrices;
     int TotalCost;
     int Balance;
-    uint8_t Reserved[3];
+    int Discount;
+    int Transaction;
+    int EnergyCost;
+    int ParkingFee;
+    uint32_t RemainAmount;
+    uint8_t Reserved[1];
 } AccountInfo;
 
+typedef struct stCabinetDCMVersion {
+    uint8_t CabinetModelName[32];
+    uint8_t CabinetBoolLoaderVersion[32];
+    uint8_t CabinetKernelVersion[32];
+    uint8_t CabinetRFSystemVersion[32];
+    uint8_t CabinetPrimaryVersion[32];
+    uint8_t CabinetIPAddr[32];
+}PCDCMVer;
+
+typedef struct stCabinetOtherVersion {
+    uint8_t CabinetRelay0Version[32];
+    uint8_t CabinetRelay1Version[32];
+    uint8_t CabinetFanVersion[32];
+}PCOthVer;
+
+typedef struct stCabinetEachPsuVersion {
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PCnPsuVer;
+
 #pragma pack(pop)
 
 #endif /* _DO_COMM_H_ */

+ 14 - 2
EVSE/Projects/DD360/Apps/ModuleEvComm/Ev_Comm.c

@@ -13,7 +13,7 @@
 
 #include "Ev_Comm.h"
 #include "Module_EvComm.h"
-
+#include "../Config.h"
 //------------------------------------------------------------------------------
 int PackageIdCmd(int cmd)
 {
@@ -22,14 +22,26 @@ int PackageIdCmd(int cmd)
 
 void SendCmdToEvboard(int cmd, uint8_t *data, uint8_t dataLen)
 {
+    DcCommonInfo* ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     int fd = GetCanFd();
     struct can_frame frame;
-
+    int i;
+    int len = 0;
+    char _info[1024];
     frame.can_id = cmd;
     frame.can_dlc = dataLen;
     memcpy(frame.data, data, sizeof(frame.data));
 
     write(fd, &frame, sizeof(struct can_frame));
+
+    if (ShmDcCommonData->showCanPackage) {
+        len += sprintf(&_info[len], "CAN Dispenser => EV Tx:\t[0x%X] ", cmd);
+        for (i = 0; i < dataLen; i++) {
+            len += sprintf(&_info[len], "%X ", data[i]);
+        }
+        len += sprintf(&_info[len], "\n");
+        printf("%s",_info);
+    }
 }
 
 //------------------------------------------------------------------------------

+ 154 - 43
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -226,6 +226,54 @@ static void AddrAssignment(uint8_t *data)
     //}
 }
 
+void CheckEvConnect(int gunIndex)
+{
+    int isSameType = FALSE;
+    int isDisconnect = FALSE;
+    int gunType = _Type_CCS_2;
+    struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+    struct InfoCodeData* pInfoCode = (struct InfoCodeData*)GetShmInfoCodeData();
+    struct ChargingInfoData* pDcChargingInfo_0 = (struct ChargingInfoData*)GetDcChargingInfoData(0);
+    struct ChargingInfoData* pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(1);
+
+    if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) {
+        isSameType = TRUE;
+        isDisconnect = ShmDcCommonData->pGunInfo[0].EVLoseFlag | ShmDcCommonData->pGunInfo[1].EVLoseFlag;
+        gunType = pDcChargingInfo_0->Type;
+    } else {
+        isDisconnect = ShmDcCommonData->pGunInfo[gunIndex].EVLoseFlag;
+        gunType = pDcChargingInfo->Type;
+    }
+
+    //log_info("ShmDcCommonData->EVDisconnectFlag[%d]:%d", gunIndex, ShmDcCommonData->EVDisconnectFlag[gunIndex]);
+    if (isDisconnect) {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = YES;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = YES;
+            break;
+        }
+
+    } else {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = NO;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = NO;
+            break;
+        }
+    }
+}
+
 void CANReceiver(int fd)
 {
     pid_t canRecPid;
@@ -255,7 +303,11 @@ void CANReceiver(int fd)
         uint8_t lastConnTemp[2] = {0, 0};
         struct can_frame frame;
         ChillerTemp chiilerTemp = {0};
+        time_t CCS_PlugoutTimer[2] = { 0 };
         struct ChargingInfoData *pDcChargingInfo = NULL;
+        int len = 0;
+        char _info[1024];
+        int i;
 
         pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
         pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -269,11 +321,33 @@ void CANReceiver(int fd)
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
 
-        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        ShmDcCommonData->pGunInfo[0].EVLoseTimer = time((time_t*)NULL);
+        ShmDcCommonData->pGunInfo[1].EVLoseTimer = time((time_t*)NULL);
 
+        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        CCS_PlugoutTimer[0] = time((time_t*)NULL);
+        CCS_PlugoutTimer[1] = time((time_t*)NULL);
         while (isContinue) {
             memset(&frame, 0, sizeof(struct can_frame));
 
+            for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
+                pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
+                // 檢查是否有收到EV小板訊號
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[_index].EVLoseTimer > 3) &&
+                    !ShmDcCommonData->pGunInfo[_index].EVLoseFlag &&
+                    pDcChargingInfo->SystemStatus != S_UPDATE && !ShmDcCommonData->debugflag) {
+
+                    ShmDcCommonData->pGunInfo[_index].EVLoseTimer = time((time_t*)NULL);
+                    ShmDcCommonData->pGunInfo[_index].EVLoseFlag = TRUE;
+
+                    system("/sbin/ip link set can0 down");
+                    sleep(1);
+                    system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
+                    system("/sbin/ip link set can0 up");
+                }
+                CheckEvConnect(_index);
+            }
+
             nbytes = read(fd, &frame, sizeof(struct can_frame));
             if (nbytes <= 0) {
                 usleep(10000);
@@ -293,6 +367,16 @@ void CANReceiver(int fd)
             intCmd = (int) (frame.can_id & CAN_EFF_MASK & 0xFFFFFF00);
 
             recvID = ((uint8_t) (frame.can_id & 0x000000FF)); // 0x01 or 0x02
+            
+            if (ShmDcCommonData->showCanPackage) {
+                len = 0;
+                len += sprintf(&_info[len], "CAN Dispenser <= EV Rx:\t[0x%X] ", frame.can_id);
+                for (i = 0; i < nbytes; i++) {
+                    len += sprintf(&_info[len], "%X ", frame.data[i]);
+                }
+                len += sprintf(&_info[len], "\n");
+                printf("%s", _info);
+            }
 
             for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {                    // 假設有找到回應的 Index
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
@@ -325,6 +409,9 @@ void CANReceiver(int fd)
                 usleep(10000);
                 continue;
             }
+            // Reset Connect Timer
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun);
             gunTypeIndex = pDcChargingInfo->type_index;
@@ -341,13 +428,30 @@ void CANReceiver(int fd)
                             pSysInfo->CurGunSelected = targetGun;
 #endif                        
                     } else if (frame.data[0] == UNPLUG) {
-                        log_info("Conn %d, Unplug. ", targetGun);
+                        if (pDcChargingInfo->Type != _Type_CCS_2)
+                            log_info("Conn %d, Unplug. ", targetGun);
                         strcpy( (char *) pDcChargingInfo->EVCCID, "");
                     } else {
                         log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]);
                     }
+                    if(pDcChargingInfo->RemoteStartFlag == YES) {
+                        pSysInfo->CurGunSelected = targetGun;
+                    }
+                }
+                // CCS 小板確認拔除三秒
+                if (pDcChargingInfo->Type == _Type_CCS_2) {
+                    if (frame.data[0] == UNPLUG) {
+                        if ((time((time_t*)NULL) - CCS_PlugoutTimer[targetGun]) > 3) {
+                            if (pDcChargingInfo->ConnectorPlugIn != frame.data[0])
+                                log_info("CCS Conn %d, Unplug. ", targetGun);
+                        } else {
+                            frame.data[0] = PLUG;
+                        }
+                    } else {
+                        CCS_PlugoutTimer[targetGun] = time((time_t*)NULL);
+                        frame.data[0] = PLUG;
+                    }
                 }
-
                 pDcChargingInfo->ConnectorPlugIn = frame.data[0];
                 pDcChargingInfo->PilotVoltage = frame.data[1];
 
@@ -424,6 +528,7 @@ void CANReceiver(int fd)
 
                     if (frame.data[1] > pDcChargingInfo->EvBatterySoc) {
                         pDcChargingInfo->EvBatterySoc = frame.data[1];
+                        log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc);
                     }
                 }
                 //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove
@@ -446,8 +551,8 @@ void CANReceiver(int fd)
                 //printf("RemainChargingDuration = %d",  pDcChargingInfo->RemainChargingDuration);
 
                 if (pDcChargingInfo->Type == _Type_Chademo) {
-                    //if (ShmCHAdeMOData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d CHAdeMO board status = %d ", targetGun, ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus);
                         ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -456,8 +561,8 @@ void CANReceiver(int fd)
                     ShmCHAdeMOData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmCHAdeMOData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //if (ShmGBTData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d GB Board status = %d ", targetGun, ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -466,7 +571,8 @@ void CANReceiver(int fd)
                     ShmGBTData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmGBTData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
+                    if (ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus != frame.data[0] && frame.data[0] != 0xFF) {
+                        log_info("Gun%d CCS board status = %d ", targetGun, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
                 }
@@ -549,20 +655,23 @@ void CANReceiver(int fd)
 
                     pDcChargingInfo->ChillerTemp = maxChillerTemp;
                 }
+                if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
+                    maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
+                    //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
+                    //    printConnTemp = YES;
+                    //}
+                    maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
+                    if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
+                    {
+                        lastConnTemp[targetGun] = maxConnTemp;
+                        printConnTemp = YES;
+                    }
 
-                maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
-                //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
-                //    printConnTemp = YES;
-                //}
-                maxConnTemp = getAvageTemp(maxConnTemp,targetGun);
-                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
-                {
-                    lastConnTemp[targetGun] = maxConnTemp;
-                    printConnTemp = YES;
+                    pDcChargingInfo->ConnectorTemp = maxConnTemp;
+                } else {
+                    //log_info("Connector%d Tmep is zero:[%d,%d]", gunTypeIndex, ShmDcCommonData->ConnectorTemp[gunTypeIndex][0],
+                    //    ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]);
                 }
-
-                pDcChargingInfo->ConnectorTemp = maxConnTemp;
-
                 //紀錄槍頭和水冷機溫度, 在系統狀態變化或溫度大於150
                 if ((ShmDcCommonData->SystemModeChange[targetGun] == YES) ||
                         (printConnTemp == YES) ||
@@ -573,11 +682,13 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d",
+                    log_info("Conn %d max temp = %d, chiller = [%d %d], chiller2 = [%d %d]",
                              targetGun,
-                             maxConnTemp,
-                             chillerTemp[0],
-                             chillerTemp[1]);
+                             pDcChargingInfo->ConnectorTemp,
+                             chiilerTemp.Temp[0],
+                             chiilerTemp.Temp[1],
+                             chiilerTemp.Temp[2],
+                             chiilerTemp.Temp[3]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
@@ -645,25 +756,25 @@ void CANReceiver(int fd)
                 break;
             case ACK_EVCCID_REQ:
 
-                        if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
-                            pDcChargingInfo->Type == _Type_CCS_2)
-                        {
-                            {
-                                memset (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        0,
-                                        sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
-                                memcpy (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        frame.data, frame.can_dlc );
-                            }
-
-                            sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
-                                    frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
-
-                            pDcChargingInfo->EVCCID [17] = '\0';
-                            log_info( "************* Gun %d->EVCCID = %s ************* ", targetGun, pDcChargingInfo->EVCCID );
-                        }
+                if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
+                    pDcChargingInfo->Type == _Type_CCS_2)
+                {
+                    {
+                        memset (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                0,
+                                sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
+                        memcpy (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                frame.data, frame.can_dlc );
+                    }
+
+                    sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
+                            frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
+
+                    pDcChargingInfo->EVCCID [17] = '\0';
+                    log_info( "Gun %d->EVCCID = %s ", targetGun, pDcChargingInfo->EVCCID );
+                }
                 break;
             default:
                 log_info("EV board = %d, Ack none defined. intCmd = %d  ", targetGun, intCmd);

+ 5 - 2
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -1028,7 +1028,7 @@ int main(int argc, char *argv[])
                 //if (waitPsuVolwithRealyVol(gunIndex) == NO) {
                 //    continue;
                 //}
-
+                GetEvBatteryInfo(gunIndex, pDcChargingInfo->Evboard_id); //DS60-120 add
                 // 計算 Power
                 pDcChargingInfo->PresentChargingPower =
                     ((float)((pDcChargingInfo->PresentChargingVoltage) *
@@ -1040,7 +1040,7 @@ int main(int argc, char *argv[])
                     chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                 } else {
                     int passTime = pDcChargingInfo->PresentChargedDuration - chargingTime[gunIndex];
-
+                    
                     if (passTime > 0) {
                         float changingPow = (pDcChargingInfo->PresentChargingPower) * passTime / 3600;
                         if (pSysConfig->BillingData.isBilling) {
@@ -1048,9 +1048,12 @@ int main(int argc, char *argv[])
                         }
 
                         pDcChargingInfo->PresentChargedEnergy += changingPow;
+
+                        ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption += changingPow;
                         pDcChargingInfo->PowerConsumption += changingPow;
                         chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                     }
+                    
                 }
 
                 // 開始確認車端是否同意開始充電

+ 24 - 24
EVSE/Projects/DD360/Apps/ModuleInternalComm/FanBoard.c

@@ -20,6 +20,7 @@ static struct SysInfoData *pSysInfo = NULL;
 static struct AlarmCodeData *pAlarmCode = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
+static DcCommonInfo* ShmDcCommonData = NULL;
 
 static int Uart5Fd = 0;
 static struct timeval gFanBoardRunTimer;
@@ -149,8 +150,8 @@ static void GetFanSpeedByFunction(void)
 static void SetRtcData_Fan(void)
 {
     struct timeb csuTime;
-    struct tm *tmCSU;
-    Rtc rtc = {0};
+    struct tm* tmCSU;
+    Rtc rtc = { 0 };
 
     ftime(&csuTime);
     tmCSU = localtime(&csuTime.time);
@@ -186,30 +187,42 @@ static void SetRtcData_Fan(void)
 static void SetModelName_Fan(void)
 {
     if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
-        return;
-    } else
-        log_info("******** Set Model name FAIL = %s ************", pSysConfig->ModelName);
+        log_info("Set Model name PASS = %s ", pSysConfig->ModelName);
+    }
 }
 
 static void GetFwAndHwVersion_Fan(void)
 {
-    Ver ver = {0};
+    Ver ver = { 0 };
 
     if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // FanModuleData
-        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        strcpy((char*)ShmFanModuleData->version, ver.Version_FW);
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleFwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s1 = %s ", ver.Version_FW);
     }
 
     if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleHwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s2 = %s ", ver.Version_HW);
     }
 }
 
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
 static void fanBoardPorcess(void)
 {
     if (ShmFanModuleData->SelfTest_Comp == NO) {
@@ -217,8 +230,8 @@ static void fanBoardPorcess(void)
     }
 
     if (ShmFanModuleData->SelfTest_Comp == YES ||
-            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
-            pSysInfo->FanModuleFwRev[0] != '\0') {
+        strlen((char*)pSysInfo->FanModuleFwRev) != 0 ||
+        pSysInfo->FanModuleFwRev[0] != '\0') {
         ShmFanModuleData->SelfTest_Comp = YES;
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
@@ -239,19 +252,6 @@ static void fanBoardPorcess(void)
     }
 }
 
-static void fanBoardSelfTest(void)
-{
-    if (ShmFanModuleData->SelfTest_Comp == YES) {
-        return;
-    }
-
-    GetFwAndHwVersion_Fan();
-    SetModelName_Fan();
-    SetRtcData_Fan();
-    sleep(1);
-    gettimeofday(&gFanBoardRunTimer, NULL);
-}
-
 void FanBoardTask(int uartFD)
 {
 #if defined NO_FAN_BOARD || defined DD360ComBox

+ 6 - 1
EVSE/Projects/DD360/Apps/ModuleInternalComm/LEDlight.c

@@ -127,9 +127,10 @@ static void SetLedColor(void)
                 led_color.Connect_2_Red = _colorBuf;
             }
         } else {
+
+            // 實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -158,6 +159,8 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+
             }
 
             // --------------------------------------------------------------------------
@@ -191,6 +194,8 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+
             }
 
         }

+ 56 - 14
EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c

@@ -25,7 +25,7 @@ static DcCommonInfo *ShmDcCommonData = NULL;
 static struct WARNING_CODE_INFO *pSysWarning = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
-
+static struct GBTData* ShmGBTData = NULL;
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
@@ -36,7 +36,8 @@ static uint16_t fanSpeedSmoothValue = 1000;
 static Led_Color cur_led_color = {COLOR_MIN_LV};
 static Led_Color led_color;
 static struct timeval _led_priority_time;
-
+int ReservationLed;
+time_t ReservationFlashTimer;
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
@@ -361,10 +362,17 @@ static void GetGfdAdc(void)
 void CheckOutputPowerOverCarReq(uint8_t index)
 {
     struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
-
+    ShmGBTData = (struct GBTData*)GetShmGBTData();
     float fireV = pDcChargingInfo->FireChargingVoltage;
     float carV = pDcChargingInfo->EvBatteryMaxVoltage * 10;
-
+    /*
+    log_info("PresentChargingVoltage:%f, FireChargingVoltage:%f ", pDcChargingInfo->PresentChargingVoltage * 10, pDcChargingInfo->FireChargingVoltage);
+    log_info("fireV:%f, carV:%f, _isOvpChkTimeFlag:%d", fireV, carV, _isOvpChkTimeFlag[index]);
+    log_info("EvBatterytargetVoltage:%f", pDcChargingInfo->EvBatterytargetVoltage);
+    if (pDcChargingInfo->Type == _Type_GB) {
+        log_info("GB EV Board Status:%d", ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
+    }
+    */
     if ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 1500 &&
             (pDcChargingInfo->Type == _Type_Chademo ||
              pDcChargingInfo->Type == _Type_CCS_2 ||
@@ -1398,16 +1406,16 @@ static void fanBoardPorcess(void)
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
             //GetPsuTempForFanSpeed();
-            GetFanSpeedByFunction();
+            //GetFanSpeedByFunction();
             GetFanSpeed();
             pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
             gettimeofday(&gFanBoardRunTimer, NULL);
-
+            /*
             ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-
+            */
             //log_info("set fan = %d ", ShmFanModuleData->SetFan1Speed);
             SetFanModuleSpeed();
         }
@@ -1488,11 +1496,9 @@ static void SetLedColor(void)
     } else {
         if (pSysInfo->IsAlternatvieConf) {
             if ((chargingData_1->SystemStatus == S_BOOTING ||
-                    chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    chargingData_1->SystemStatus == S_IDLE ) &&
                     (chargingData_2->SystemStatus == S_BOOTING ||
-                     chargingData_2->SystemStatus == S_IDLE ||
-                     chargingData_2->SystemStatus == S_RESERVATION)) {
+                     chargingData_2->SystemStatus == S_IDLE)) {
 #if defined DD360Audi
                 led_color.Connect_1_Green = _colorBuf;
                 led_color.Connect_1_Blue = _colorBuf;
@@ -1528,12 +1534,25 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
-            }
+            } else if (chargingData_1->SystemStatus == S_RESERVATION ||
+                chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
 
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
         } else {
+            //實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -1562,13 +1581,20 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
             }
 
 
             // --------------------------------------------------------------------------
             if (chargingData_2->SystemStatus == S_BOOTING ||
                     chargingData_2->SystemStatus == S_IDLE ||
-                    chargingData_2->SystemStatus == S_RESERVATION ||
                     chargingData_2->SystemStatus == S_MAINTAIN) {
                 if (chargingData_2->IsAvailable == NO) {
                     led_color.Connect_2_Green = COLOR_MIN_LV;
@@ -1596,6 +1622,14 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
             }
 
         }
@@ -1663,6 +1697,14 @@ static void LEDBoardProcess(void)
         //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
         //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
         //}
+        if (time((time_t*)NULL) - ReservationFlashTimer >= 3) {
+            ReservationFlashTimer = time((time_t*)NULL);
+            if (ReservationLed)
+                ReservationLed = 0;
+            else
+                ReservationLed = 1;
+        }
+
         SetLedColor();
         gettimeofday(&_led_priority_time, NULL);
     }

+ 258 - 301
EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -31,229 +31,6 @@ static struct ChargingInfoData *pDcChargingInfo = NULL;
 static struct ChargingInfoData *pAcChargingInfo = NULL;
 static DcCommonInfo *ShmDcCommonData            = NULL;
 
-bool needReloadQr = true;
-bool _saftydetect = false;
-bool _isShow = false; //DS60-120 add
-uint8_t _showInformIndex = 0; //DS60-120 add
-
-int _port;
-//char* pPortName         = "/dev/ttyO2";
-char *pPortName           = "/dev/ttyS3";
-char *moduleName          = "DMT80480T070_09WT";
-uint8_t _totalCount;
-uint8_t acgunCount;
-//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
-
-uint8_t ac_ani_battery_level    = _BATTERY_LEVEL_FOR_MAP_LV5;
-uint8_t isDiffStatus            = false;
-uint8_t isChangeBattMap         = false;
-// 當前選擇的槍號
-#if defined DD360Audi
-short _currentPage              = _LCM_SELECT_GUN;
-short _oldPage                  = _LCM_SELECT_GUN;
-#else
-short _currentPage              = _LCM_NONE;
-short _oldPage                  = _LCM_NONE;
-#endif //defined DD360Audi
-uint8_t _gunIndex               = 0;
-bool _wifi_conn_status          = false;
-bool _battery_display_ani       = false;
-uint8_t _curPage_index          = 0;
-bool _page_reload               = false;
-
-// LCM - HW
-uint8_t _everyPageRollChange    = 0;
-short __logo                    = 0x0000;
-short __conn_status             = 0x0030;
-short __ethernet_status         = 0x0032;
-short __3G4G_status             = 0x0036;
-short __3G4G_status1            = 0x0037;
-short __3G4G_move_status        = 0x0038;
-short __wifi_status             = 0x003C;
-
-short __sel_gun_btn             = 0x0040;
-short __ret_home_btn            = 0x0042;
-short __stop_method_btn         = 0x0044;
-short __lcm_version             = 0x004A;
-short __qr_code                 = 0x0250;
-short __main_rfid               = 0x0052;
-short __main_qr                 = 0x0054;
-short __main_app                = 0x0056;
-
-short __plug_in_arrow           = 0x0060;
-
-short __conn_line               = 0x0066;
-
-short __gun_type_index          = 0x0070;
-short __cmp_gun_type_index      = 0x0080; ////For Audi
-short __batt_map_empty          = 0x0090; ////For Audi
-short __qr_code_pre             = 0x0280;
-
-short __side_top                = 0x0090;
-short __side_down               = 0x0092;
-short __side_mid                = 0x0094;
-
-short __conn_line_chag          = 0x0096;
-short __batt_map                = 0x0100;
-short __soc_value_charging      = 0x0102;
-short __remain_time_map         = 0x0106;
-short __power_map               = 0x0108;
-short __energy_map              = 0x010A;
-short __remain_time_tx          = 0x0110;
-
-short __trp_remain_time_map     = 0x0116;
-short __trp_power_map           = 0x0118;
-short __trp_energy_map          = 0x011A;
-
-short __output_eng_tx           = 0x0120;
-short __total_out_eng_tx        = 0x0130;
-short __conn_line_comp          = 0x0140;
-short __charging_fee_map        = 0x0146;
-short __charging_fee_tx         = 0x0150;
-
-short __money_by_rate           = 0x0200;
-short __money_rate              = 0x0220;
-short __money_rate_map          = 0x0230;
-
-//DS60-120 add
-short __csu_ver_string          = 0x0300;
-short __csu_ver_value           = 0x0310;
-short __fan_speed_string        = 0x0390;
-short __fan_speed_value         = 0x0400;
-
-short __dc1_ver_string          = 0x0320;
-short __dc1_ver_value           = 0x0330;
-short __dc2_ver_string          = 0x0340;
-short __dc2_ver_value           = 0x0350;
-short __eth0_ip_string          = 0x0360;
-short __eth0_ip_value           = 0x0370;
-short __sn_string               = 0x0410;
-short __sn_value                = 0x0420;
-
-//For Audi, for select gun
-short __left_gun_map            = 0x0260;
-short __right_gun_map           = 0x0262;
-short __add_chk_btn             = 0x0264;
-//short __station_id            = 0x0270;
-short __balance                 = 0x0270;
-short __remain_balance          = 0x0280;
-short __custStationIdL1         = 0x0450;
-//short __custStationIdL2       = 0x0470;
-short _emergency_map            = 0x011C;
-short __logo_cmp                = 0x014A;
-// ICON ID
-uint8_t _disappear              = 0;
-uint8_t _disconnect             = 1;
-uint8_t _connect                = 2;
-uint8_t _warning                = 3;
-uint8_t _arrow_dark             = 4;
-uint8_t _arrow_light            = 5;
-uint8_t _3G4G_disconnect        = 6;
-uint8_t __3G4G_connect          = 7;
-uint8_t _wifi_disconnect        = 8;
-uint8_t _wifi_connect           = 9;
-uint8_t _logo                   = 10;
-uint8_t _conn_map1              = 11;
-uint8_t _conn_map2              = 12;
-uint8_t _sel_gun_btn            = 13;
-uint8_t _back_home_btn          = 14;
-uint8_t _stop_charging_btn      = 15;
-uint8_t _stop_charging_btn_scan = 16;
-uint8_t _chademo_dark           = 17;
-uint8_t _ccs_dark               = 18;
-uint8_t _gbt_dark               = 19;
-uint8_t _actype_dark            = 20;
-uint8_t _chademo_light          = 21;
-uint8_t _ccs_light              = 22;
-uint8_t _gbt_light              = 23;
-uint8_t _actype_light           = 24;
-uint8_t _main_none_rfid         = 25;
-uint8_t _main_rfid              = 26;
-uint8_t _main_none_app          = 27;
-uint8_t _main_app               = 28;
-uint8_t _main_none_qr           = 29;
-uint8_t _main_qr                = 30;
-uint8_t _charging_map1          = 31;
-uint8_t _charging_map2          = 32;
-uint8_t _battery_empty          = 33;
-uint8_t _battery_cap_20         = 34;
-uint8_t _battery_cap_40         = 35;
-uint8_t _battery_cap_60         = 36;
-uint8_t _battery_cap_80         = 37;
-uint8_t _battery_cap_100        = 38;
-uint8_t _battery_map            = 39;
-uint8_t _power_map              = 40;
-uint8_t _time_map               = 41;
-uint8_t _complete_map           = 42;
-uint8_t _battery_soc_20         = 43;
-uint8_t _battery_soc_40         = 44;
-uint8_t _battery_soc_60         = 45;
-uint8_t _battery_soc_80         = 46;
-uint8_t _battery_soc_100        = 47;
-uint8_t _battery_eng_map        = 48;
-uint8_t _money_map              = 49;
-uint8_t _elapse_time_map        = 50;
-uint8_t _charging_money         = 51;
-//uint8_t _side_none_rfid       = 52;
-//uint8_t _side_rfid            = 53;
-//uint8_t _side_none_app        = 54;
-//uint8_t _side_app             = 55;
-//uint8_t _side_none_qr         = 56;
-//uint8_t _side_qr              = 57;
-uint8_t _eth_disconnect         = 52; //58;
-uint8_t _eth_connect            = 53; //59;
-
-uint8_t _chademo_dark_cmp       = 54;
-uint8_t _ccs_dark_cmp           = 55;
-uint8_t _gbt_dark_cmp           = 56;
-uint8_t _actype_dark_cmp        = 57;
-uint8_t _chademo_light_cmp      = 58;
-uint8_t _ccs_light_cmp          = 59;
-uint8_t _gbt_light_cmp          = 60;
-uint8_t _actype_light_cmp       = 61;
-
-uint8_t _logo_cmp               = 62;
-uint8_t _battery_eng_trp_map    = 63;
-uint8_t _money_trp_map          = 64;
-uint8_t _elapse_time_trp_map    = 65;
-#if defined DD360Audi
-////For Audi
-uint8_t _left_gun_disable_map   = 66;
-uint8_t _left_gun_enable_map    = 67;
-uint8_t _right_gun_disable_map  = 68;
-uint8_t _right_gun_enable_map   = 69;
-uint8_t _select_gun_btn         = 70;
-uint8_t _emergency_disable_map  = 72;
-// For replug
-struct timespec showReplugStrTimer;
-struct timespec showFullTargetTimer;
-short __show_StatusString_value_1 = 0x0460;
-short __show_StatusString_value_2 = 0x0462;
-uint8_t _showfulltarget_1       = 73;
-uint8_t _showfulltarget_2       = 74;
-uint8_t _showReplugStr_1        = 75;
-uint8_t _showReplugStr_2        = 76;
-// Select Gun for Audi
-short __show_selectgun_value    = 0x0464;
-uint8_t _showselectgun_left     = 77;
-uint8_t _showselectgun_right    = 78;
-// Wait for gun plugin Audi
-short __show_waitgunplug_value    = 0x0468;
-uint8_t _showwaitgunplug_left     = 80;
-uint8_t _showwaitgunplug_right    = 81;
-#else
-short __show_handshark_value    = 0x0464;
-short __show_GFD_value          = 0x0466;
-short __show_precharge_value    = 0x0468;
-
-uint8_t _show_handshark_dark    = 67;
-uint8_t _show_handshark_light   = 68;
-uint8_t _show_GFD_dark          = 69;
-uint8_t _show_GFD_light         = 70;
-uint8_t _show_precharge_dark    = 71;
-uint8_t _show_precharge_light   = 72;
-#endif
 //#define log_info(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_error(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -432,8 +209,8 @@ void ReadMsgFromLcm(uint8_t *msg, uint8_t readLen)
             {
                 if(strcmp((char *)pSysInfo->LcmHwRev, "") != EQUAL)
                     strcpy((char *)pSysInfo->LcmHwRev, moduleName);
-
-                ShmDcCommonData->LcmFwVersion = atoi((char *)(msg + 7));
+                if (atoi((char*)(msg + 7)) != 0)
+                    ShmDcCommonData->LcmFwVersion = atoi((char*)(msg + 7));
                 //printf("msg = %d \n", ShmDcCommonData->LcmFwVersion);
     //              printf("msg = %x \n", *(msg + 7));
     //              printf("msg = %x \n", *(msg + 8));
@@ -521,7 +298,25 @@ void DisplayValueToLcm(short address, uint8_t *data, uint8_t len)
 
     WriteCmdToLcm(cmd, cmd[2] + 3);
 }
+void DisplayFeeValueToLcm(short address, uint8_t* data, uint8_t len)
+{
+    uint8_t cmd[256];
+    memset(cmd, 0x00, sizeof(cmd));
 
+    cmd[0] = CMD_TITLE_1;
+    cmd[1] = CMD_TITLE_2;
+    cmd[2] = 0x03 + len;
+    cmd[3] = CMD_MULTI_WRITE;
+    cmd[4] = address >> 8;
+    cmd[5] = address & 0x00FF;
+
+    for (uint8_t count = 0; count < len; count++)
+    {
+        cmd[12 + count] = *(data + count);
+    }
+
+    WriteCmdToLcm(cmd, cmd[2] + 3);
+}
 void ChangeDisplay2Value(short address, short value)
 {
     uint8_t data[2];
@@ -579,7 +374,7 @@ void ChangeWarningFunc()
     //log_info("WarningCount = %d ", pSysWarning->WarningCount);
 //#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
     for (i = 0; (i + pSysWarning->PageIndex * 5) < pSysWarning->WarningCount; i++) {
-        log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
+        //log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
         memset(cmd, 0x00, sizeof(cmd));
         if ((i) >= 5) {
             break;
@@ -840,6 +635,7 @@ uint8_t demoCount = 0;
 void DemoFunction()
 {
     if (demoCount == 0) {
+        /*
         pSysWarning->WarningCount = 6;
         memcpy(&pSysWarning->WarningCode[0][0], "000001", 7);
         memcpy(&pSysWarning->WarningCode[1][0], "000002", 7);
@@ -847,24 +643,38 @@ void DemoFunction()
         memcpy(&pSysWarning->WarningCode[3][0], "000004", 7);
         memcpy(&pSysWarning->WarningCode[4][0], "000005", 7);
         memcpy(&pSysWarning->WarningCode[5][0], "000006", 7);
+        */
     } else {
         if (demoCount == 20) {
             pSysInfo->PageIndex = _LCM_IDLE;
-        } else if (demoCount == 80) {
+            /*
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_AUTHORIZING;
-        } else if (demoCount == 100) {
+        } else if (demoCount == 80) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_COMP;
-        } else if (demoCount == 120) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_FAIL;
-        } else if (demoCount == 140) {
+            */
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_PRE_CHARGE;
-        } else if (demoCount == 180) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_CHARGING;
+        } else if (demoCount == 160) {
+            pSysInfo->PageIndex = _LCM_COMPLETE;
         }
     }
+    pSysInfo->CurGunSelected = LEFT_GUN_NUM;
+    sprintf((char*)ShmDcCommonData->QRCodeString, "%s", pSysConfig->SystemId);
 
-    if (demoCount < 180) {
+    sprintf((char*)ShmDcCommonData->pGunInfo[LEFT_GUN_NUM].ReceiptInfo, "%s", pSysConfig->SystemId);
+    pSysConfig->BillingData.isBilling = 1;
+    sprintf((char*)ShmDcCommonData->DefaultPriceString, "AM10:~10:00:$ 2, AM10:00~PM05:00:$ 3, PM05:00~AM00:00:$ 2");
+
+
+    if (demoCount <= 200) {
         demoCount++;
+    } else {
+        demoCount = 0;
     }
 }
 
@@ -1117,6 +927,7 @@ void ChangeRemainTime(int sec)
     s = (sec - (3600 * h) - (m * 60));
     sprintf((char *)value, "%02d:%02d:%02d", h, m, s);
     string2ByteArray(value, cmd);
+
     DisplayValueToLcm(__remain_time_tx, cmd, sizeof(cmd));
 }
 
@@ -1126,12 +937,10 @@ void ChangeChargingEnergyValue(float energy)
     uint8_t value[10];
 
     memset(cmd, 0x00, sizeof(cmd));
-    if (energy >= 0.05) {
-        energy -= 0.05;
-    }
-    sprintf((char *) value, "%.1f kWh", energy);
+
+    sprintf((char*)value, "%.4f kWh", energy);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__total_out_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_energy, cmd, sizeof(cmd));
 }
 
 void ChangeChargingPowerValue(float pow)
@@ -1146,7 +955,7 @@ void ChangeChargingPowerValue(float pow)
 //  pow = (max - min) * rand() / (RAND_MAX + 1.0) + min;
     sprintf((char *) value, "%.1f kW", pow);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__output_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_power, cmd, sizeof(cmd));
 }
 
 void ChangeChargingFeeValue(float fee)
@@ -1161,6 +970,62 @@ void ChangeChargingFeeValue(float fee)
     DisplayValueToLcm(__charging_fee_tx, cmd, sizeof(cmd));
 }
 
+void ChangeEnergyCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+    if (fee >= 0 )
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_EnergyCost, cmd, sizeof(cmd));
+}
+void ChangeParkingFeeValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_ParkingFee, cmd, sizeof(cmd));
+}
+void ChangeTotalCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_TotalCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_TotalCost, cmd, sizeof(cmd));
+}
 void DisplayMoneyRate(float money)
 {
     uint8_t cmd[8];
@@ -1186,6 +1051,13 @@ void DisplayMoneyCur(uint8_t *cur)
     string2ByteArray(buf, cmd);
     DisplayValueToLcm(__money_rate, cmd, sizeof(cmd));
 }
+void DisplayReceipt(char* pString)
+{
+    char data[200];
+    memset(data, '\0', sizeof(data));
+    strcpy(data, pString);
+    DisplayValueToLcm(__Receipt_value, data, 200);
+}
 
 void RefreshPageAnimation(uint8_t value)
 {
@@ -1579,6 +1451,29 @@ void DisplayInfoEthIp(bool isShow, uint8_t *ip)
     }
 }
 
+void DisplayInfoConsumption(bool isShow)
+{
+    float data = 0;
+    if (isShow) {
+        uint8_t value[20];
+
+        memset(value, 0x00, sizeof(value));
+        strcpy((char*)value, "PWCT >");
+        DisplayValueToLcm(__eth0_ip_string, value, sizeof(value));
+        memset(value, 0x00, sizeof(value));
+        data = ShmDcCommonData->pConsumption.Gun1_Consumption +
+            ShmDcCommonData->pConsumption.Gun2_Consumption +
+            ShmDcCommonData->pConsumption.Gun3_Consumption +
+            ShmDcCommonData->pConsumption.Gun4_Consumption;
+
+        sprintf((char*)value,"%.4f",data);
+
+        DisplayValueToLcm(__eth0_ip_value, value, sizeof(value));
+    } else {
+        ChangeDisplay2Value(__eth0_ip_string, _disappear);
+        ChangeDisplay2Value(__eth0_ip_value, _disappear);
+    }
+}
 void Show4GRssi(bool isShow, int dbValue)
 {
     if (isShow) {
@@ -1745,8 +1640,7 @@ void InformationShow()
             DisplayInfoCsuVer(show, pSysInfo->CsuRootFsFwRev);
             DisplayInfoSpeed(show, pSysInfo->SystemFanRotaSpeed);
             DisplayInfoSN(show, pSysConfig->SerialNumber);
-
-            DisplayInfoEthIp(show, pSysConfig->Eth0Interface.EthIpAddress);
+            DisplayInfoConsumption(show);
             DisplayInfoGun1Ver(show, pSysInfo->Connector1FwRev);
             if (_totalCount > 1) {
                 DisplayInfoGun2Ver(show, pSysInfo->Connector2FwRev);
@@ -1808,14 +1702,58 @@ void ChangeTimeValue(uint8_t time)
     string2ByteArray(value, cmd);
     DisplayValueToLcm(0x1290, cmd, sizeof(cmd));
 }
+void ShowDateTime()
+{
+    struct timeb SeqEndTime;
+    struct tm* tm;
+    char _date[20];
+    char _time[20];
+    char _am_pm[10];
+
+    ftime(&SeqEndTime);
+    SeqEndTime.time = time(NULL);
+    
+    tm = localtime(&SeqEndTime.time);
+
+    sprintf(_date, "%04d/%02d/%02d",
+        tm->tm_year + 1900,
+        tm->tm_mon + 1,
+        tm->tm_mday);
 
+    if (tm->tm_hour >= 12) {
+        sprintf(_am_pm,"p.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour-12,
+            tm->tm_min);
+    } else {
+        sprintf(_am_pm, "a.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour,
+            tm->tm_min);
+    }
+    DisplayValueToLcm(__date_map, _date, strlen(_date)+1);
+    DisplayValueToLcm(__time_map, _time, strlen(_time)+1);
+    DisplayValueToLcm(__time_am_pm, _am_pm, strlen(_am_pm)+1);
+}
+uint8_t old_string[255];
+void ShowAnimationPrice(char* pString)
+{
+    uint8_t cmd[230];
+    memset(cmd, 0x00, sizeof(cmd));
+    string2ByteArray((uint8_t*)pString,cmd);
+    int len = strlen(pString);
+
+    if (strcmp((char*)old_string, pString) != EQUAL) {
+        strcpy((char*)old_string, pString);
+        DisplayFeeValueToLcm(__Animation_Price, cmd, sizeof(cmd));
+    }
+}
 void ProcessPageInfo()
 {
     _page_reload = IsPageReloadChk();
     pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
     struct InfoCodeData *pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData();
     struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
-    uint8_t i;
 
     // 隨插即充 - 可省略該按鈕 //DS60-120 add
     if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) {
@@ -1827,6 +1765,9 @@ void ProcessPageInfo()
         }
     }
     showPhihongLogo(false);
+    // Show Time
+    ShowDateTime();
+
     switch (_currentPage) {
 #if defined DD360Audi
     case _LCM_SELECT_GUN: ////For Audi
@@ -1842,7 +1783,7 @@ void ProcessPageInfo()
 #endif //defined DD360Audi
 
     case _LCM_IDLE: {
-
+        ChangeDisplayMoneyInfo();
         if (pSysConfig->isRFID) {
             ChangeDisplay2Value(__main_rfid, _main_rfid);
         } else {
@@ -1871,6 +1812,8 @@ void ProcessPageInfo()
         //if (FirstPageChanged() == YES || needReloadQr || _page_reload) {
         if (pSysConfig->isQRCode) {
             needReloadQr = false;
+            ChangeQrCode_Idle((char*)ShmDcCommonData->QRCodeString);
+            /*
             if (pSysConfig->QRCodeMadeMode == NO) {
                 //uint8_t len = strlen((char *)pSysConfig->SystemId);
                 ChangeQrCode_Idle((char *)pSysConfig->SystemId);
@@ -1879,6 +1822,7 @@ void ProcessPageInfo()
                 ChangeQrCode_Idle((char *)pSysConfig->QRCodeContent);
             }
             //ChangeQrCode_Idle((char *)pSysConfig->SystemId);
+            */
         }
         //}
 
@@ -1979,7 +1923,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2008,7 +1952,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
 
@@ -2047,6 +1991,8 @@ void ProcessPageInfo()
             }
         }
 
+        ChangeDisplay2Value(__money_by_rate, _disappear);
+
         gunTargetIndex = 0; //DS60-120 add
         for (uint8_t i = 0; i < _totalCount; i++) {
             if (_totalCount == 1 && acgunCount <= 0) { //DS60-120 add
@@ -2111,53 +2057,16 @@ void ProcessPageInfo()
             if (_currentPage == _LCM_PRE_CHARGE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
                     ChangeBattMapAndValue(_currentPage, pDcChargingInfo->EvBatterySoc);
-                    uint8_t precharg_time = (GetPreChargeTimeoutValue(pDcChargingInfo->PreChargeTimer)/1) / uSEC_VAL;
-                    if (precharg_time > PRECHARGING_TTIMEOUT)
-                        precharg_time = PRECHARGING_TTIMEOUT;
-                    ChangeTimeValue(PRECHARGING_TTIMEOUT- precharg_time);
-
-                    if (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                            pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EV) {
-                        pDcChargingInfo->_SaftyDetect = false;
-                        ChangeDisplay2Value(__show_handshark_value, _show_handshark_light);
-                        ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                        ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-
-                    } else if (pDcChargingInfo->SystemStatus == S_PREPARING_FOR_EVSE) {
-                        if (pDcChargingInfo->Type == _Type_Chademo || pDcChargingInfo->Type == _Type_GB) {
-                            if (pDcChargingInfo->_SaftyDetect == false ) {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                                if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                    pDcChargingInfo->_SaftyDetect = true;
-                            } else {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                            }
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                        }
-                    } else if (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0 ||
-                            pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1) {
-                        if (pDcChargingInfo->_SaftyDetect == false ) {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                            if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                pDcChargingInfo->_SaftyDetect = true;
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                        }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
                     } else {
-                        ChangeDisplay2Value(__show_handshark_value, _disappear);
-                        ChangeDisplay2Value(__show_GFD_value, _disappear);
-                        ChangeDisplay2Value(__show_precharge_value, _disappear);
+                        ShowAnimationPrice("");
                     }
                 }
             } else if (_currentPage == _LCM_CHARGING && !isShowAc) {
@@ -2177,7 +2086,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2190,6 +2099,21 @@ void ProcessPageInfo()
                     } else {
                         ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                        ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee > 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
+                    } else {
+                        ShowAnimationPrice("");
+                    }
                 }
             } else if (_currentPage == _LCM_COMPLETE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
@@ -2207,8 +2131,9 @@ void ProcessPageInfo()
                     } else {
                         ChangeChargingPowerValue(0);
                     }
+
 #if 1
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2224,6 +2149,23 @@ void ProcessPageInfo()
                             ChangeBalanceValue(__remain_balance, i);
                         }
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    if (strlen((char*)ShmDcCommonData->pGunInfo[i].ReceiptInfo) > 0) {
+                        DisplayReceipt(ShmDcCommonData->pGunInfo[i].ReceiptInfo);
+                        ChangeDisplay2Value(__receipt_backgroud, _receipt_bk);
+                    } else {
+                        DisplayReceipt("");
+                        ChangeDisplay2Value(__receipt_backgroud, _disappear);
+                    }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee >= 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+                    
 #else
                     ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2274,6 +2216,8 @@ void ProcessPageInfo()
                     if (pSysConfig->isQRCode) {
                         needReloadQr = false;
                         //ChangeQrCode_Charge((char *)pSysConfig->SystemId); //DS60-120 remove
+                        ChangeQrCode_Charge((char*)ShmDcCommonData->QRCodeString);
+                        /*
                         if (pSysConfig->QRCodeMadeMode == NO) {
                             //uint8_t len = strlen((char *)pSysConfig->SystemId);
                             ChangeQrCode_Charge((char *)pSysConfig->SystemId);
@@ -2281,6 +2225,7 @@ void ProcessPageInfo()
                             //uint8_t len = strlen((char *)pSysConfig->QRCodeContent);
                             ChangeQrCode_Charge((char *)pSysConfig->QRCodeContent);
                         }
+                        */
                     }
                 }
             }
@@ -2302,6 +2247,11 @@ void ProcessPageInfo()
             break;
             }
         }
+#else
+        if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == 1) {
+            ChangeToOtherPage(_LCM_EMERGENCY);
+            break;
+        }
 #endif
 
         break;
@@ -2325,10 +2275,11 @@ void ChangeDisplayMoneyInfo()
             DisplayMoneyRate(ShmSelectGunInfo->PricesInfo[curGun].UserPrices);
         } else {
 #endif //defined DD360Audi
-            if (tmCSU->tm_hour <= 23) {
-                pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
-                DisplayMoneyRate(pSysConfig->BillingData.Cur_fee);
-            }
+
+            pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
+            ChangeDisplay2Value(__money_by_rate, _disappear);
+            ShowAnimationPrice(ShmDcCommonData->DefaultPriceString);
+
 
             if (pSysConfig->BillingData.Currency <= 53) {
                 DisplayMoneyCur((uint8_t *)GetCurrency(pSysConfig->BillingData.Currency));
@@ -2340,6 +2291,7 @@ void ChangeDisplayMoneyInfo()
         ChangeDisplay2Value(__money_rate_map, _disappear);
         ChangeDisplay2Value(__money_by_rate, _disappear);
         ChangeDisplay2Value(__money_rate, _disappear);
+        ShowAnimationPrice("");
     }
 }
 
@@ -2390,6 +2342,7 @@ void DefaultIconStatus()
     for (uint8_t i = 0; i < 3; i++) {
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
+    ChangeDisplay2Value(__sel_gun_btn, _disappear);
 
     if (pSysInfo->IsAlternatvieConf == YES || _totalCount == 1) {
         ChangeDisplay2Value(__sel_gun_btn, _disappear);
@@ -2429,7 +2382,7 @@ int main(void)
     pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
-    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();;
+    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
     ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
     struct StatusCodeData *ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();;
@@ -2438,6 +2391,7 @@ int main(void)
     _port = CreateCommunicationLcmPort();
     uint8_t changeWarningPriority = 0;
     uint8_t curWarningCount = 255;
+    uint8_t changeInfoPriority = 0;
     ChangeBackLight(true);
     _totalCount = pSysConfig->TotalConnectorCount;
     acgunCount = pSysConfig->AcConnectorCount;
@@ -2450,7 +2404,7 @@ int main(void)
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
 
-    uint8_t _verShowCount = 3;
+    uint8_t _verShowCount = 5;
     DefaultIconStatus(); //DS60-120 add
 
     while (_port != -1) {
@@ -2501,10 +2455,13 @@ int main(void)
 #if defined DD360Audi
             ChangeDisplayMoneyInfo();
 #else
-            if (changeWarningPriority == 0) { ////For Audi
-                ChangeDisplayMoneyInfo();
-                InformationShow();
+            InformationShow();
+            /*
+            if (changeInfoPriority == 0) { ////For Audi
+                //ChangeDisplayMoneyInfo();
+                
             }
+            */
 #endif //defined DD360Audi
 
             changeWarningPriority >= 15 ? (_battery_display_ani = true) : (_battery_display_ani = false);

+ 278 - 4
EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.h

@@ -1,6 +1,35 @@
 #ifndef MODULE_LCM_CTRL_H_
 #define MODULE_LCM_CTRL_H_
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
 
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+#include    "../Define/define.h"
+#include    "../Config.h"
 //------------------------------------------------------------------------------
 #define DEFAULT_AC_INDEX                        (2)
 
@@ -17,10 +46,6 @@
 
 #define CMD_BACKLIGHT                           (0x01)
 #define CMD_REGISTER                            (0x03)
-
-//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
-#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
-
 //------------------------------------------------------------------------------
 enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_EMP = 0x00,
@@ -31,4 +56,253 @@ enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_LV5 = 0x05,
 };
 
+
+//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
+#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
+#define CTEP_VERSION 002
+bool needReloadQr = true;
+bool _saftydetect = false;
+bool _isShow = false; //DS60-120 add
+uint8_t _showInformIndex = 0; //DS60-120 add
+
+int _port;
+//char* pPortName         = "/dev/ttyO2";
+char* pPortName = "/dev/ttyS3";
+char* moduleName = "DMT80480T070_09WT";
+uint8_t _totalCount;
+uint8_t acgunCount;
+//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
+
+uint8_t ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV5;
+uint8_t isDiffStatus = false;
+uint8_t isChangeBattMap = false;
+// 當前選擇的槍號
+#if defined DD360Audi
+short _currentPage = _LCM_SELECT_GUN;
+short _oldPage = _LCM_SELECT_GUN;
+#else
+short _currentPage = _LCM_NONE;
+short _oldPage = _LCM_NONE;
+#endif //defined DD360Audi
+uint8_t _gunIndex = 0;
+bool _wifi_conn_status = false;
+bool _battery_display_ani = false;
+uint8_t _curPage_index = 0;
+bool _page_reload = false;
+
+// LCM - HW
+uint8_t _everyPageRollChange = 0;
+short __logo = 0x0000;
+short __conn_status = 0x0030;
+short __ethernet_status = 0x0032;
+short __3G4G_status = 0x0036;
+short __3G4G_status1 = 0x0037;
+short __3G4G_move_status = 0x0038;
+short __wifi_status = 0x003C;
+
+short __sel_gun_btn = 0x0040;
+short __ret_home_btn = 0x0042;
+short __stop_method_btn = 0x0044;
+short __lcm_version = 0x004A;
+short __qr_code = 0x0250;
+short __main_rfid = 0x0052;
+short __main_qr = 0x0054;
+short __main_app = 0x0056;
+
+short __plug_in_arrow = 0x0060;
+
+short __conn_line = 0x0066;
+
+short __gun_type_index = 0x0070;
+short __cmp_gun_type_index = 0x0080; ////For Audi
+short __batt_map_empty = 0x0090; ////For Audi
+short __qr_code_pre = 0x0280;
+
+short __side_top = 0x0090;
+short __side_down = 0x0092;
+short __side_mid = 0x0094;
+
+short __conn_line_chag = 0x0096;
+short __batt_map = 0x0100;
+short __soc_value_charging = 0x0102;
+short __remain_time_map = 0x0106;
+short __power_map = 0x0108;
+short __energy_map = 0x010A;
+short __remain_time_tx = 0x0110;
+
+short __trp_remain_time_map = 0x0116;
+short __trp_power_map = 0x0118;
+short __trp_energy_map = 0x011A;
+
+short __output_eng_tx = 0x0120;
+short __total_out_eng_tx = 0x0130;
+short __conn_line_comp = 0x0140;
+short __charging_fee_map = 0x0146;
+short __charging_fee_tx = 0x0150;
+
+short __money_by_rate = 0x0200;
+short __money_rate = 0x0220;
+short __money_rate_map = 0x0230;
+
+//DS60-120 add
+short __csu_ver_string = 0x0300;
+short __csu_ver_value = 0x0310;
+short __fan_speed_string = 0x0390;
+short __fan_speed_value = 0x0400;
+
+short __dc1_ver_string = 0x0320;
+short __dc1_ver_value = 0x0330;
+short __dc2_ver_string = 0x0340;
+short __dc2_ver_value = 0x0350;
+short __eth0_ip_string = 0x0360;
+short __eth0_ip_value = 0x0370;
+short __sn_string = 0x0410;
+short __sn_value = 0x0420;
+
+//For Audi, for select gun
+short __left_gun_map = 0x0260;
+short __right_gun_map = 0x0262;
+short __add_chk_btn = 0x0264;
+//short __station_id            = 0x0270;
+short __balance = 0x0270;
+short __remain_balance = 0x0280;
+short __custStationIdL1 = 0x0450;
+//short __custStationIdL2       = 0x0470;
+short _emergency_map = 0x011C;
+short __logo_cmp = 0x014A;
+
+// CTEP
+short __remain_time = 0x0110;
+short __present_power = 0x0120;
+short __present_energy = 0x0130;
+short __date_map = 0x0470;
+short __time_map = 0x0480;
+short __time_am_pm = 0x0489;
+short __Prepare_EnergyCost = 0x0500;
+short __Prepare_ParkingFee = 0x0510;
+short __Charge_EnergyCost = 0x0610;
+short __Charge_ParkingFee = 0x0620;
+short __Charge_TotalCost = 0x0630;
+short __Complete_EnergyCost = 0x0640;
+short __Complete_ParkingFee = 0x0650;
+short __Complete_TotalCost = 0x0660;
+short __Receipt_value = 0x0670;
+short __Animation_Price = 0x6010;
+short __receipt_backgroud = 0x0700;
+// ICON ID
+uint8_t _disappear = 0;
+uint8_t _disconnect = 1;
+uint8_t _connect = 2;
+uint8_t _warning = 3;
+uint8_t _arrow_dark = 4;
+uint8_t _arrow_light = 5;
+uint8_t _3G4G_disconnect = 6;
+uint8_t __3G4G_connect = 7;
+uint8_t _wifi_disconnect = 8;
+uint8_t _wifi_connect = 9;
+uint8_t _logo = 10;
+uint8_t _conn_map1 = 11;
+uint8_t _conn_map2 = 12;
+uint8_t _sel_gun_btn = 13;
+uint8_t _back_home_btn = 14;
+uint8_t _stop_charging_btn = 15;
+uint8_t _stop_charging_btn_scan = 16;
+uint8_t _chademo_dark = 17;
+uint8_t _ccs_dark = 18;
+uint8_t _gbt_dark = 19;
+uint8_t _actype_dark = 20;
+uint8_t _chademo_light = 21;
+uint8_t _ccs_light = 22;
+uint8_t _gbt_light = 23;
+uint8_t _actype_light = 24;
+uint8_t _main_none_rfid = 25;
+uint8_t _main_rfid = 26;
+uint8_t _main_none_app = 27;
+uint8_t _main_app = 28;
+uint8_t _main_none_qr = 29;
+uint8_t _main_qr = 30;
+uint8_t _charging_map1 = 31;
+uint8_t _charging_map2 = 32;
+uint8_t _battery_empty = 33;
+uint8_t _battery_cap_20 = 34;
+uint8_t _battery_cap_40 = 35;
+uint8_t _battery_cap_60 = 36;
+uint8_t _battery_cap_80 = 37;
+uint8_t _battery_cap_100 = 38;
+uint8_t _battery_map = 39;
+uint8_t _power_map = 40;
+uint8_t _time_map = 41;
+uint8_t _complete_map = 42;
+uint8_t _battery_soc_20 = 43;
+uint8_t _battery_soc_40 = 44;
+uint8_t _battery_soc_60 = 45;
+uint8_t _battery_soc_80 = 46;
+uint8_t _battery_soc_100 = 47;
+uint8_t _battery_eng_map = 48;
+uint8_t _money_map = 49;
+uint8_t _elapse_time_map = 50;
+uint8_t _charging_money = 51;
+//uint8_t _side_none_rfid       = 52;
+//uint8_t _side_rfid            = 53;
+//uint8_t _side_none_app        = 54;
+//uint8_t _side_app             = 55;
+//uint8_t _side_none_qr         = 56;
+//uint8_t _side_qr              = 57;
+uint8_t _eth_disconnect = 52; //58;
+uint8_t _eth_connect = 53; //59;
+
+uint8_t _chademo_dark_cmp = 54;
+uint8_t _ccs_dark_cmp = 55;
+uint8_t _gbt_dark_cmp = 56;
+uint8_t _actype_dark_cmp = 57;
+uint8_t _chademo_light_cmp = 58;
+uint8_t _ccs_light_cmp = 59;
+uint8_t _gbt_light_cmp = 60;
+uint8_t _actype_light_cmp = 61;
+
+uint8_t _logo_cmp = 62;
+uint8_t _battery_eng_trp_map = 63;
+uint8_t _money_trp_map = 64;
+uint8_t _elapse_time_trp_map = 65;
+#if defined DD360Audi
+////For Audi
+uint8_t _left_gun_disable_map = 66;
+uint8_t _left_gun_enable_map = 67;
+uint8_t _right_gun_disable_map = 68;
+uint8_t _right_gun_enable_map = 69;
+uint8_t _select_gun_btn = 70;
+uint8_t _emergency_disable_map = 72;
+// For replug
+struct timespec showReplugStrTimer;
+struct timespec showFullTargetTimer;
+short __show_StatusString_value_1 = 0x0460;
+short __show_StatusString_value_2 = 0x0462;
+uint8_t _showfulltarget_1 = 73;
+uint8_t _showfulltarget_2 = 74;
+uint8_t _showReplugStr_1 = 75;
+uint8_t _showReplugStr_2 = 76;
+// Select Gun for Audi
+short __show_selectgun_value = 0x0464;
+uint8_t _showselectgun_left = 77;
+uint8_t _showselectgun_right = 78;
+// Wait for gun plugin Audi
+short __show_waitgunplug_value = 0x0468;
+uint8_t _showwaitgunplug_left = 80;
+uint8_t _showwaitgunplug_right = 81;
+#else
+short __show_handshark_value = 0x0464;
+short __show_GFD_value = 0x0466;
+short __show_precharge_value = 0x0468;
+uint8_t _receipt_bk = 67;
+
+uint8_t _show_handshark_dark = 67;
+uint8_t _show_handshark_light = 68;
+uint8_t _show_GFD_dark = 69;
+uint8_t _show_GFD_light = 70;
+uint8_t _show_precharge_dark = 71;
+uint8_t _show_precharge_light = 72;
+#endif
+
+
 #endif //MODULE_LCM_CTRL_H_

+ 11 - 2
EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -345,16 +345,19 @@ static void checkChillerStatus(Gpio_out *gpio)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
     static ChillerInfo _chiller;
+    struct FanModuleData* ShmFanModuleData = (struct FanModuleData*)GetShmFanModuleData();;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[0].withChiller = TRUE;
     }
 
     if ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[1].withChiller = TRUE;
     }
 
     if (chillerCount == 0) {
@@ -362,7 +365,9 @@ static void checkChillerStatus(Gpio_out *gpio)
         return;
     }
 
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++) {
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        if (!ShmDcCommonData->pGunInfo[gunIndex].withChiller)
+            continue;
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
@@ -380,6 +385,7 @@ static void checkChillerStatus(Gpio_out *gpio)
                 if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
                 {
                     pChillerInfo->ChillerSwitch = NO;
+                    ShmFanModuleData->SetFan1Speed = 0;
                 }
             }
             else
@@ -411,12 +417,15 @@ static void checkChillerStatus(Gpio_out *gpio)
     }
 
     uint8_t _chillerNeedOn = NO;
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++)
     {
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
         if(pChillerInfo->ChillerSwitch == YES)
         {
             _chillerNeedOn = YES;
+            if (chillerCount >= 2) {
+                ShmFanModuleData->SetFan1Speed = 7000;
+            }
         }
     }
 

+ 78 - 9
EVSE/Projects/DD360/Apps/ReadCmdline.c

@@ -210,11 +210,15 @@ void RunStatusProc(char *v1, char *v2)
 
         if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
             // get
-            printf ("index = %x, status = %x (%d)\n",
+            printf ("index = %x, status = %x (%d) Reservation is :%s\n",
                     _index,
                     pDcChargingInfo->SystemStatus,
-                    pDcChargingInfo->IsAvailable);
-            printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
+                    pDcChargingInfo->IsAvailable,
+                    ShmDcCommonData->pGunInfo[_index].ReservationStatus ? "trigger" : "expired");
+            if (ShmDcCommonData->pGunInfo[_index].ReservationStatus)
+                printf("Reservation idTag:%s\n", ShmDcCommonData->pGunInfo[_index].ReservationID);
+
+            printf("SystemTimeoutFlag = %d, PageIndex = %d\n",
                     pSysInfo->SystemTimeoutFlag, pSysInfo->PageIndex);
         } else {
             // set
@@ -335,6 +339,21 @@ void GetFwVerProc(void)
                      "      exit | c | C\n"
                      "      help | ? | h\n";
 
+
+    printf("ModelName = %s\r\n", pSysConfig->ModelName);
+    printf("DC Main Version = %s \n", pSysInfo->CsuRootFsFwRev);
+    printf("407 FW Version = %s\n", ShmPrimaryMcuData->version);
+    printf("Gun 0 FW Version = %s \n", pSysInfo->Connector1FwRev);
+    printf("Gun 1 FW Version = %s \n", pSysInfo->Connector2FwRev);
+    printf("Relay Board Version = %s \n", pSysInfo->RelayModuleFwRev);
+    printf("FAN Version = %s \n", pSysInfo->FanModuleFwRev);
+    printf("LED Version = %s \n", pSysInfo->LedModuleFwRev);
+    printf("LCM FW Version = V.%03d \n", ShmDcCommonData->LcmFwVersion);
+    printf("Dispenser Network Information checked: IP = % s Netmask = % s, Gateway = % s \n",
+        pSysConfig->Eth0Interface.EthIpAddress,
+        pSysConfig->Eth0Interface.EthSubmaskAddress,
+        pSysConfig->Eth0Interface.EthGatewayAddress);
+    /*
     while (isContinue) {
         if (readCmdKey(CMD_KEY_WAIT) == NO) {
             continue;
@@ -379,6 +398,7 @@ void GetFwVerProc(void)
         }
 
     }//while
+    */
 }
 
 void CreateOneError(char *v1)
@@ -476,6 +496,7 @@ void GetSystemInfo()
     printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
             pSysConfig->MaxChargingPower,
             pSysConfig->MaxChargingCurrent);
+    pSysConfig->ShowInformation = YES;
 }
 
 void ChangeGunNum()
@@ -538,6 +559,7 @@ void SetDebugMode(char *v1)
     int mode = atoi(v1);
 
     ShmDcCommonData->debugflag = mode;
+    pSysConfig->ShowInformation = mode;
     printf("Set Debug Mode:%d\n" , ShmDcCommonData->debugflag);
 }
 
@@ -723,6 +745,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         return;
     }
     //kill ev task
+    ShmDcCommonData->debugflag = YES;
     system("killall Module_EvComm");
 
     pSysInfo->CurGunSelected = _GunIndex;
@@ -947,7 +970,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             pDcChargingInfo->PresentChargingPower = 0;
 
             if (stopChg == pSysConfig->TotalConnectorCount) {
-
+                ShmDcCommonData->debugflag = NO;
                 system("/root/Module_EvComm &");
                 sleep(3);
 
@@ -1194,6 +1217,7 @@ static void writeOTPTemp(void)
         usleep(sleepTime);
     }//while
 }
+
 void writeChillerStatus(char *v1)
 {
     if (ShmDcCommonData->debugflag == YES) {
@@ -1205,6 +1229,35 @@ void writeChillerStatus(char *v1)
     } else
         printf("Please open Debug mode\n");
 }
+
+void showNetworkPage(char* v1)
+{
+    ShmDcCommonData->showNetPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showNetPackage)
+        printf("Show Network Package on\n");
+    else
+        printf("Show Network Package off\n");
+}
+
+void showCANBUSPage(char* v1)
+{
+    ShmDcCommonData->showCanPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showCanPackage)
+        printf("Show CAN Bus Package on\n");
+    else
+        printf("Show CAN Bus Package off\n");
+}
+void setSystemTime(char* date,char* time)
+{
+    char _setTime[30];
+    char cmdBuf[50];
+    sprintf(_setTime, "%s %s", date, time);
+    printf("Set Timer:%s", _setTime);
+    sprintf((char*)cmdBuf, "date -u -s \"%s\" >> /dev/null &", _setTime);
+    system((char*)cmdBuf);
+    system("hwclock -w -u");
+    system("hwclock -s");
+}
 static void writeGunAndChillerTemp(void)
 {
     uint8_t _GunIndex = 0;
@@ -1280,7 +1333,16 @@ static void writeGunAndChillerTemp(void)
         usleep(sleepTime);
     }//while
 }
+void ShowPowerConsumption(char* v1)
+{
+    printf("Dispenser Gun0 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[0].PowerConsumption);
+    printf("Dispenser Gun1 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[1].PowerConsumption);
 
+    printf("Power Consumption Gun1:%.4f, Gun2:%.4f, Gun3:%.4f, Gun4:%.4f", ShmDcCommonData->pConsumption.Gun1_Consumption,
+        ShmDcCommonData->pConsumption.Gun2_Consumption,
+        ShmDcCommonData->pConsumption.Gun3_Consumption,
+        ShmDcCommonData->pConsumption.Gun4_Consumption);
+}
 int main(void)
 {
     uint8_t _GunIndex = 0;
@@ -1305,7 +1367,10 @@ int main(void)
                      "       tempW                             : write connector header and Chiller temperature\r\n"
                      "       tempR                             : print connector header and chiller temperature\r\n"
                      "       OTP                               : Write OTP temperature\r\n"
-                     "       chiller                           : set chiller on/off"
+                     "       chiller                           : set chiller on/off\r\n"
+                     "       netdump                           : show network package\r\n"
+                     "       candump                           : show can package\r\n"
+                     "       powerconsumption                  : Show Power Consumption\n"
                      "\r\n";
 
     if (CreateAllCsuShareMemory() == FAIL) {
@@ -1456,10 +1521,6 @@ int main(void)
             }
             SetChargingInfoCCID(newString[1], newString[2]);
         } else if (strcmp(newString[0], "strchg") == 0) {
-            if (ShmDcCommonData->debugflag == NO ) {
-                printf("Please Open debug mode\n");
-                continue;
-            }
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             if (strcmp(newString[1], "auto") == 0) {
                 newString[2][0] = 0;
@@ -1482,6 +1543,14 @@ int main(void)
             writeOTPTemp();
         } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
             writeChillerStatus(newString[1]);
+        } else if (strcmp(newString[0], "netdump") == 0) { //印出網路封包
+            showNetworkPage(newString[1]);
+        } else if (strcmp(newString[0], "candump") == 0) { //印出網路封包
+            showCANBUSPage(newString[1]);
+        } else if (strcmp(newString[0], "time") == 0) {  //設定系統時間
+            setSystemTime(newString[1], newString[2]);
+        } else if (strcmp(newString[0], "powerconsumption") == 0) { // Power Consumption
+            ShowPowerConsumption(newString[1]);
         } else {
             printf("%s\n", usageMsg);
         }

+ 5 - 1
EVSE/Projects/DD360/Apps/SelectGun/SelectGun.h

@@ -61,7 +61,11 @@ typedef struct StPricesInfo {
     //float TotalCost;            //unit = 0.01 dollar, value / 100
     float Balance;              //unit = 0.01 dollar, value / 100
     //float DefaultPrices;        //unit = 0.01 dollar, value / 100
-    uint8_t Reserved[4];
+    float Discount;
+    int TransactionId;
+    float EnergyCost;
+    float ParkingFee;
+    float RemainAmount;
 } PricesInfo;
 
 //typedef struct StOperativeInfo {

+ 44 - 7
EVSE/Projects/DD360/Apps/ShareMemory/shmMem.c

@@ -38,6 +38,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 
 static SelectGunInfo *ShmSelectGunInfo = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
@@ -300,6 +301,15 @@ void *GetShmOCPP16Data(void)
     return ShmOCPP16Data;
 }
 
+void* GetShmOCPP20Data(void)
+{
+    if (ShmOCPP20Data == NULL) {
+        return NULL;
+    }
+
+    return ShmOCPP20Data;
+}
+
 void *GetShmSelectGunInfo(void)
 {
     if (ShmSelectGunInfo == NULL) {
@@ -604,6 +614,21 @@ int InitOCPPShmMem(void)
     return PASS;
 }
 
+int InitOCPP20ShmMem(void)
+{
+    int MeterSMId = FAIL;
+
+    if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) {
+        log_info("Get OCPP20 share memory error");
+        return FAIL;
+    } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void*)-1) {
+        log_info("Create OCPP20 share memory error");
+        return FAIL;
+    }
+
+    return PASS;
+}
+
 int InitLEDShmMem(void)
 {
     int MeterSMId = FAIL;
@@ -905,16 +930,15 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
         }
         break;
 
+    case 'V': // Liquid CCS1 combo
+    case 'F': // Liquid CCS2 combo
     case 'T': // Rema CCS1
     case 'D': // Rema CCS2
     case 'U': // CCS1 combo
     case 'E': // CCS2 combo
-    case 'V': // Liquid CCS1 combo
-    case 'F': // Liquid CCS2 combo
     case 'M': // 80A CCS2
     case 'N': // 80A CCS1
-    case 'P': // Phoenix CCS2 500A 水冷
-    case 'R': // Phoenix CCS1 500A 水冷
+    case 'P': // 急電弓
         if (CCS_QUANTITY > gGunIndexInfo.CcsIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->CcsChargingData[gGunIndexInfo.CcsIndex];
 
@@ -934,16 +958,25 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
                 gGunIndexInfo.CcsIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
-            if(typeValue == 'P')
-            {
+            if(typeValue == 'P') {
                 pDcChargingInfo->PantographFlag = YES;
-            }
+            } else if (typeValue == 'V') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Liquid;
+            } else if (typeValue == 'F') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Liquid;
+            } else if (typeValue == 'T' || typeValue == 'U' || typeValue == 'N') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Natural;
+            } else if (typeValue == 'D' || typeValue == 'E' || typeValue == 'M') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Natural;
+            } else
+                pDcChargingInfo->CCSGunType = _TYPE_CCS_NONE;
         } else {
             result = false;
         }
         break;
 
     case 'G':  // GBT DC
+    case 'B': // GBT YG PT100
         if (GB_QUANTITY > gGunIndexInfo.GbIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->GbChargingData[gGunIndexInfo.GbIndex];
 
@@ -1114,6 +1147,10 @@ int CreateAllCsuShareMemory(void)
         return ret;
     }
 
+    if ((ret = InitOCPP20ShmMem()) == FAIL) {
+        return ret;
+    }
+
     if ((ret = InitSelectGunShmMem()) == FAIL) {
         return ret;
     }

+ 1 - 0
EVSE/Projects/DD360/Apps/ShareMemory/shmMem.h

@@ -42,6 +42,7 @@ void *GetShmSysInfoData(void);
 void *GetShmSysWarningInfo(void);
 
 void *GetShmOCPP16Data(void);
+void* GetShmOCPP20Data(void);
 
 void *GetShmCHAdeMOData(void);
 void *GetShmGBTData(void);

BIN
EVSE/Projects/DD360/Apps/UnsafetyOutputTask


BIN
EVSE/Projects/DD360/Images/ramdisk.gz


BIN
EVSE/Projects/DD360/output/DoComm


BIN
EVSE/Projects/DD360/output/FactoryConfig


BIN
EVSE/Projects/DD360/output/Module_ChkSysTask


BIN
EVSE/Projects/DD360/output/Module_DoComm


BIN
EVSE/Projects/DD360/output/Module_EvComm


BIN
EVSE/Projects/DD360/output/Module_EventLogging


BIN
EVSE/Projects/DD360/output/Module_InternalComm


BIN
EVSE/Projects/DD360/output/Module_LcmControl


BIN
EVSE/Projects/DD360/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360/output/Module_UpdateFW


BIN
EVSE/Projects/DD360/output/ReadCmdline


BIN
EVSE/Projects/DD360/output/UnsafetyOutputTask


BIN
EVSE/Projects/DD360/output/main


+ 1 - 0
EVSE/Projects/DD360Audi/Apps/CSU/Ethernet.c

@@ -194,6 +194,7 @@ void InitEthernet(void)
     //system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up");
 
     if (pSysConfig->Eth0Interface.EthDhcpClient == 0) {
+        system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
         sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &",
                 pSysConfig->SystemId);
         system(tmpbuf);

+ 10 - 7
EVSE/Projects/DD360Audi/Apps/CSU/Primary.c

@@ -23,7 +23,7 @@ typedef struct StLedConfig {
     uint8_t AcContactor: 1;                     //bit 6,    H: ON,      L:OFF
     uint8_t Reserved: 1;                        //bit 7 reserved
 } LedConfig;
-
+time_t showInfoTimer;
 //------------------------------------------------------------------------------
 static uint8_t checkCabinetEthConnectState(LedConfig *ledConfig)
 {
@@ -217,6 +217,7 @@ static void checkChargingInfoByDC(uint8_t systemStatus)
 
     switch (systemStatus) {
     case S_IDLE:
+    case S_RESERVATION:
         if (isDetectPlugin()) {
             _DetectPlugInTimeout();
             StopSystemTimeoutDet();
@@ -436,12 +437,14 @@ void ChkPrimaryStatus(void)
     }
 
     //DS60-120 add
-    //if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
-    //        ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
-    //    pSysConfig->ShowInformation = YES;
-    //} else {
-    //    pSysConfig->ShowInformation = NO;
-    //}
+    if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
+            ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
+        pSysConfig->ShowInformation = YES;
+        showInfoTimer = time((time_t*)NULL);
+    } else {
+        if ( (time((time_t*)NULL) - showInfoTimer) > 3 )
+            pSysConfig->ShowInformation = NO;
+    }
 
     if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
             !leftBtnPush &&

+ 19 - 5
EVSE/Projects/DD360Audi/Apps/CSU/RFID.c

@@ -16,7 +16,7 @@
 static char *rfidPortName = "/dev/ttyS2";
 
 static bool isCardScan = false;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 static bool canStartCharging(void)
 {
@@ -140,7 +140,8 @@ static void UserScanFunction(void)
             stopReq = i;
         }
 
-        if ((pDcChargingInfo->SystemStatus == S_IDLE &&
+        if (((pDcChargingInfo->SystemStatus == S_IDLE ||
+            pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                 pDcChargingInfo->IsAvailable == YES) ||
                 (pGunIndexInfo->AcGunIndex > 0 &&
                  pAcChargingInfo->SystemStatus == S_IDLE &&
@@ -229,7 +230,7 @@ static void UserScanFunction(void)
             strcpy((char *)pSysConfig->UserId, "");
         } else if ((pGunIndexInfo->AcGunIndex > 0 &&
                     pSysInfo->CurGunSelectedByAc == DEFAULT_AC_INDEX) ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+                   pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) {
             log_info("// LCM => Authorizing");
 
             setSelGunWaitToAuthor(pSysInfo->CurGunSelected);
@@ -266,6 +267,7 @@ void ScannerCardProcess(void)
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
     SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
 
     if (!isDetectPlugin() &&
             !isCardScan &&
@@ -299,6 +301,7 @@ void ScannerCardProcess(void)
                     // LCM => Authorize fail
                     pSysInfo->SystemPage = _LCM_AUTHORIZ_FAIL;
                     strcpy((char *)pSysConfig->UserId, "");
+                    ShmDcCommonData->AuthroizeType = IdTokenType_Central;
                 }
 
             } ClearAuthorizedFlag();
@@ -364,9 +367,10 @@ void CreateRfidFork(void)
         int fd = -1;
         int isContinue = 1;
         RFID rfid = {0};
+        int module_type = MODULE_EWT;
         fd = InitialRfidPort();
         struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-
+        ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
         //log_info("RFID fork Child's PID is %d", getpid());
 
         while (isContinue) {
@@ -378,7 +382,7 @@ void CreateRfidFork(void)
                 continue;
             }
 
-            if (getRequestCardSN(fd, 0, &rfid) == false) {
+            if (getRequestCardSN(fd, module_type, &rfid) == false) {
                 continue;
             }
 
@@ -455,6 +459,16 @@ void CreateRfidFork(void)
                 }
             }
             log_info("card number = %s", pSysConfig->UserId);
+            if (strlen((char*)pSysConfig->UserId) != 0) {
+                ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
+            }
+            if (rfid.cardType == ISO14443A) {
+                sethaltCard(fd, module_type);
+            } else if (rfid.cardType == IS014443B) {
+
+            } else if (rfid.cardType == FELICA) {
+
+            }
         }
     }
 }

+ 162 - 248
EVSE/Projects/DD360Audi/Apps/CSU/main.c

@@ -61,6 +61,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
 
 static struct ChargingInfoData *pDcChargingInfo = NULL;
@@ -82,8 +83,8 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.20.00.0000.00"; // "V0.16.00.0000.00";
-char* DebugVersion = "v1.20.0";
+char *fwVersion = "V1.21.00.0000.00"; // "V0.16.00.0000.00";
+char* DebugVersion = "v1.21.5";
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -199,7 +200,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(LEFT_GUN_NUM);
@@ -218,7 +221,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(RIGHT_GUN_NUM);
@@ -233,6 +238,7 @@ void destroySelGun(uint8_t curGun)
             ShmSelectGunInfo->PricesInfo[curGun].Balance = FAIL_BALANCE_PRICES;
         }
     }
+
 }
 
 static int waitRightGunPlugIt(uint8_t curGun)
@@ -398,52 +404,105 @@ static void checkGunOTPState(uint8_t gunIndex)
     //log_info("OTP:%d OTPR%d",pSysInfo->OTPTemp,pSysInfo->OTPTempR);
     //水冷機溫度檢測
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
-        if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
-            if (pDcChargingInfo->ChillerTemp >= pSysInfo->OTPTemp ) {
-                if (((gunIndex == 0) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                         ||
-                    ((gunIndex == 1) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-                   ) {
-                    RecordAlarmCode(gunIndex, "012323");
+        if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
+            // 單水冷機
+            // Chiller OTP
+            if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
-                }
-                else
-                {
+                    RecordAlarmCode(gunIndex, "012323");
+                } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
                 }
-            } else if (pDcChargingInfo->ChillerTemp != 0 &&
-                       pDcChargingInfo->ChillerTemp < pSysInfo->OTPTempR) {
-                //ResetChargerAlarmCode(gunIndex, "012323");
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-        } else {
-            // 沒接上 Sensor or 異常
-            //RecordAlarmCode(gunIndex, "011038");
-            //ResetChargerAlarmCode(gunIndex, "012323");
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-            if (((gunIndex == 0) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                     ||
-                ((gunIndex == 1) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-               ) {
+            // Chiller Tube OTP
+            if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-            }
-            else
-            {
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                    RecordAlarmCode(gunIndex, "012332");
+                } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[3] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                }
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
+        } else {
+            // 雙水冷機
+            if (gunIndex == LEFT_GUN_NUM) {
+                if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+                    } else if (ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            } else {
+                if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            }
         }
 
-        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
-        {
+        if (pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES) {
             RecordAlarmCode(gunIndex, "011037");
         }
     }
@@ -466,6 +525,15 @@ static void checkGunOTPState(uint8_t gunIndex)
             //ResetChargerAlarmCode(gunIndex, "012229");
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
+            if  ((gunIndex == 0) &&
+                    (strncmp((char *)&pSysConfig->ModelName[7], "J", 1) == 0)) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            } else if ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "J", 1) == 0) )) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            }
         }
         break;
 
@@ -1539,11 +1607,7 @@ uint8_t isPrechargeStatus_ccs(uint8_t gunIndex)
     uint8_t result = 0x00;
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
-        result = ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;
-    }
-
-    return result;
+    return ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;;
 }
 
 bool isEvStopCharging_ccs(uint8_t gunIndex)
@@ -1643,7 +1707,7 @@ void _DetectPlugInTimeout(void)
 	//pSysInfo->SystemPage = _LCM_COMPLETE;
 	setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING);
 #elif DD360 || DD360Combox
- 	setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE);
+ 	setChargerMode(pSysInfo->CurGunSelected, S_IDLE);
 #endif
     systemPageRestoreInit();
 }
@@ -3801,6 +3865,7 @@ static void autoStartCharging(uint8_t gunIndex)
                     ChangeGunSelectByIndex(gunIndex);
                     confirmSelGun(gunIndex);
                     pDcChargingInfo->isEVCCIDVerify = true;
+                    ShmDcCommonData->AuthroizeType = IdTokenType_MacAddress;
                     pSysInfo->SystemPage = _LCM_AUTHORIZING;
                 }
             } else
@@ -3811,6 +3876,7 @@ static void autoStartCharging(uint8_t gunIndex)
             ChangeGunSelectByIndex(gunIndex);
             confirmSelGun(gunIndex);
             pSysInfo->SystemPage = _LCM_AUTHORIZING;
+            ShmDcCommonData->AuthroizeType = IdTokenType_NoAuthorization;
         }
         if (strcmp( (char *)pSysConfig->UserId , OldUseId ) != EQUAL) {
             strcpy((char *)OldUseId, (char *)pSysConfig->UserId);
@@ -4111,9 +4177,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_Chademo:
         // 檢查樁端的 GFD 結果
         if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_chademo(gunIndex) > 6 &&
-                isPrechargeStatus_chademo(gunIndex) < 8
-           ) {
+                isPrechargeStatus_chademo(gunIndex) >= 6) {
             // 當前操作的槍號,進入 Charging
             setChargerMode(gunIndex, MODE_CHARGING);
         }
@@ -4160,8 +4224,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_GB:
         // 檢查樁端的 GFD 結果
         //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-        if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_gb(gunIndex) > 6) {
+        if (sysStatus == S_PREPARING_FOR_EVSE && isPrechargeStatus_gb(gunIndex) >= 6) {
             setChargerMode(gunIndex, MODE_CHARGING);
         }
 
@@ -4353,6 +4416,7 @@ int main(void)
     ShmRelayModuleData = (struct RelayModuleData *)GetShmRelayModuleData();
     ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
     ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
+    ShmOCPP20Data = (struct OCPP20Data*)GetShmOCPP20Data();
     ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
 	
@@ -4454,6 +4518,9 @@ int main(void)
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
 
             pDcChargingInfo->IsAvailable = DB_Get_Operactive(_index);
+            if (!DB_Get_PowerConsumption(_index)) {
+                DB_Insert_PowerConsumption(_index, 0);
+            }
         }
         DB_Reboot_Record();
     }
@@ -4484,6 +4551,9 @@ int main(void)
 
     pSysInfo->OTPTemp = GUN_OTP_VALUE;
     pSysInfo->OTPTempR = GUN_OTP_RECOVERY;
+
+    time_t ShowEVStatusTimer[2] = { 0 };
+
     for (;;) {
 
         CheckOcppStatus();
@@ -4582,14 +4652,16 @@ int main(void)
                 CheckSmartChargeProfile(gunIndex);
             }
 
-            //log_info("index = %d, ErrorCode = %s",
-            //         gunIndex,
-            //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-
+            case S_RESERVATION:
                 if (isModeChange(gunIndex)) {
-                    log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    if (pDcChargingInfo->SystemStatus == S_IDLE)
+                        log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                        log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
+                        ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
+                    }
                     pDcChargingInfo->PresentChargedDuration = 0;
                     pDcChargingInfo->RemainChargingDuration = 0;
                     pDcChargingInfo->PresentChargingVoltage = 0;//DS60-120 add
@@ -4598,9 +4670,11 @@ int main(void)
                     strcpy((char *)pDcChargingInfo->StopDateTime, "");
                     strcpy((char *)pDcChargingInfo->StartUserId, "");
                     strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "");
-
+                    
                     //Jerry add
                     memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo));
+                    memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo));
+                    DB_Get_PowerConsumption(gunIndex);
                     ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES;
                     destroySelGun(gunIndex);
                     ResetDetAlarmStatus(gunIndex); //recovery OVP status code
@@ -4611,12 +4685,6 @@ int main(void)
                     ReleaseAlarmCode(gunIndex);
                 }
 
-            case S_RESERVATION:
-                if (isModeChange(gunIndex)) {
-                    log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
-                    ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
-                }
-
                 if (pDcChargingInfo->IsAvailable == NO) {
                     setChargerMode(gunIndex, MODE_MAINTAIN);
                 }
@@ -4732,11 +4800,17 @@ int main(void)
                     } else if (pSysInfo->OrderCharging == NO_DEFINE) {
                         if (pDcChargingInfo->ConnectorPlugIn == YES &&
                                 pDcChargingInfo->IsAvailable &&
-                                pDcChargingInfo->SystemStatus == S_IDLE &&
+                                (pDcChargingInfo->SystemStatus == S_IDLE ||
+                                    pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                                 //waitSelectGunPlugIt(gunIndex)
                                 (waitRightGunPlugIt(gunIndex) == PASS ||
-                                 waitLeftGunPlugIt(gunIndex) == PASS)
-                           ) {
+                                 waitLeftGunPlugIt(gunIndex) == PASS) ) {
+                            if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                                if (strcmp((char*)pSysConfig->UserId, (char*)ShmDcCommonData->pGunInfo[gunIndex].ReservationID) != EQUAL) {
+                                    //log_info("Not Resercation ID");
+                                    continue;
+                                }
+                            }
                             log_info("-----------------2----------------- ");
                             ChangeGunSelectByIndex(gunIndex);
                             AddPlugInTimes(gunIndex);
@@ -4745,6 +4819,7 @@ int main(void)
                                      gunIndex,
                                      pDcChargingInfo->StartUserId);
                             strcpy((char *)pSysConfig->UserId, "");
+                            ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
                             // 當前操作的槍號,進入 Preparing
                             setChargerMode(gunIndex, MODE_REASSIGN_CHECK);
                             ClearDetectPluginFlag();
@@ -4758,10 +4833,6 @@ int main(void)
                         // AUDI_LCM_CHANGE
                         pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG;
                     }
-                } else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
-                    if (!isReservationExpired(gunIndex)) {
-                        pDcChargingInfo->SystemStatus = S_IDLE;
-                    }
                 } /*else if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE &&
                            (pDcChargingInfo->ConnectorPlugIn == YES &&
                             pDcChargingInfo->IsAvailable)
@@ -4775,7 +4846,8 @@ int main(void)
                         ClearDetectPluginFlag();
                         continue;
                     }
-                } */else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
+                } */
+                else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
                         pSysInfo->CurGunSelected == gunIndex && !pDcChargingInfo->isEVCCIDVerify) {
                     systemPageRestoreInit();
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
@@ -4860,7 +4932,7 @@ int main(void)
 
                 if (ShmPsuData->SystemPresentPsuQuantity > 0 &&
                         ShmPsuData->SystemAvailablePower > 10 &&
-                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 5000000) {
+                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 1000000) {
                     setChargerMode(gunIndex, MODE_PREPARE_FOR_EV);
                 }
 
@@ -4931,52 +5003,7 @@ int main(void)
                 }
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 檢查樁端的 GFD 結果
-                    if (isPrechargeStatus_chademo(gunIndex) > 5 &&
-                            isPrechargeStatus_chademo(gunIndex) < 8) {
-                        // 當前操作的槍號,進入 Charging
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    // 檢查樁端的 GFD 結果
-                    //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-                    if (isPrechargeStatus_gb(gunIndex) > 9) {
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
 
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 檢查樁端的 GFD 結果
-                    if ((pDcChargingInfo->GroundFaultStatus == GFD_PASS ||
-                            pDcChargingInfo->GroundFaultStatus == GFD_WARNING)) {
-                        setChargerMode(gunIndex, MODE_CCS_PRECHARGE_STEP0);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-                }
-#endif //0
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
 
                 // LCM => Pre-charging
@@ -5003,64 +5030,12 @@ int main(void)
                 pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]);
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012289");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    }
-                    //else if (isPrechargeStatus_gb(gunIndex) == 10 &&
-                    //           (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //             pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //            (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //             pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL))
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012290");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012288");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
+
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime) >= 5) {
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
-#endif //0
 
                 if ((evBoardStopState = isEvBoardStopChargeFlag(gunIndex)) > 0) {
                     // 板端要求停止 (錯誤)
@@ -5122,86 +5097,21 @@ int main(void)
 
                     //log_info ("terminating......................... %x ", gunIndex);
                     StopGunInfoTimeoutDet(gunIndex);
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
 
                 //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-
-                    //if (isEvStopCharging_chademo(gunIndex) == YES ||
-                    //        isPrechargeStatus_chademo(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //log_info("************ GB lock Status = %d, status = %d ",
-                    //         isEvStopCharging_gb(gunIndex),
-                    //         isPrechargeStatus_gb(gunIndex));
-
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
 
-                    //if (isEvStopCharging_gb(gunIndex) == YES ||
-                    //        isPrechargeStatus_gb(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-
-                    //if (isEvStopCharging_ccs(gunIndex) == YES &&
-                    //        (isPrechargeStatus_ccs(gunIndex) >= 53 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 0  ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 13 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 14)) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                }
-#endif //0
                 if (pDcChargingInfo->SystemStatus == S_ALARM) {
                     if (pDcChargingInfo->ConnectorPlugIn == NO &&
                             GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                        setChargerMode(gunIndex, MODE_IDLE);
+                        if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                            setChargerMode(gunIndex, MODE_RESERVATION);
+                        } else {
+                            setChargerMode(gunIndex, MODE_IDLE);
+                        }
                     }
                 } else {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
@@ -5244,9 +5154,13 @@ int main(void)
 
                 if (pDcChargingInfo->ConnectorPlugIn == NO &&
                         GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                    setChargerMode(gunIndex, MODE_IDLE);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                        setChargerMode(gunIndex, MODE_RESERVATION);
+                    } else {
+                        setChargerMode(gunIndex, MODE_IDLE);
+                    }
                     destroySelGun(gunIndex); //Jerry add
-#ifdef defined DD360 || defined DD3660ComBox
+#if defined DD360 || defined DD3660ComBox
 					//pSysInfo->SystemPage = _LCM_IDLE;
                     connectorPageRestoreIdle();
 #endif

+ 112 - 6
EVSE/Projects/DD360Audi/Apps/Config.h

@@ -135,11 +135,17 @@ enum _GUN_TYPE {
     _Type_GB,
     _Type_AC,
 };
-
+enum _CCS_GUN_TYPE {
+    _TYPE_CCS_NONE  = 0,
+    _TYPE_CCS1_Natural,
+    _TYPE_CCS1_Liquid,
+    _TYPE_CCS2_Natural,
+    _TYPE_CCS2_Liquid,
+};
 enum _LCM_INDEX {
-    _LCM_INIT          = 0x00,
-    _LCM_IDLE          = 0x01,
-    _LCM_AUTHORIZING   = 0x02,
+    _LCM_INIT = 0x00,
+    _LCM_IDLE = 0x01,
+    _LCM_AUTHORIZING = 0x02,
     _LCM_AUTHORIZ_COMP = 0x03,
     _LCM_AUTHORIZ_FAIL = 0x04,
     _LCM_WAIT_FOR_PLUG = 0x05,
@@ -147,9 +153,13 @@ enum _LCM_INDEX {
     _LCM_CHARGING      = 0x07,
     _LCM_COMPLETE      = 0x08,
     _LCM_FIX           = 0x09,
+#ifdef DD360Audi
     _LCM_SELECT_GUN    = 0x0A,
     _LCM_EMERGENCY     = 0x0B,
     _LCM_DISCONNECT    = 0x0C,
+#else
+    _LCM_EMERGENCY     = 0x0A,
+#endif
     _LCM_NONE          = 0xFF,
 };
 
@@ -267,7 +277,22 @@ enum _CCS_TYPE {
     _CCS_TYPE_CCS1 = 0,
     _CCS_TYPE_CCS2 = 1,
 };
-
+enum _WEATHER_TYPE {
+	_WEATHER_TYPE_SUN = 1,
+	_WEATHER_TYPE_CLOUDY,
+	_WEATHER_TYPE_RAIN,
+	_WEATHER_TYPE_THUNDER,
+	_WEATHER_TYPE_SNOW,
+	_WEATHER_TYPE_FOG,
+};
+enum _CREDITCARD_STATUS {
+	_CREDITCARD_IDLE,
+	_CREDITCARD_PREAUTH,
+	_CREDITCARD_PREAUTHCOMPLETE,
+	_CREDITCARD_CANCEL,
+	_CREDITCARD_SETTLEMENT,
+	_CREDITCARD_START,
+};
 //------------------------------------------------------------------------------
 //struct StructMeter {
 //    float curMeterValue;
@@ -347,7 +372,8 @@ typedef union {
     struct {
         uint8_t ChillerOTP: 1;            //chiller Temperature OVP
         uint8_t ChillerTempSensorFail: 1; //Chiller temperature sensor failure
-        uint8_t Reserved: 6;
+        uint8_t ChillerTubeOTP : 1;
+        uint8_t Reserved: 5;
     } StatusBit;
 } ChillerTempErr;
 
@@ -363,6 +389,75 @@ typedef struct StPcPsuOutput { //from power cabinet PSU output
     uint16_t Current;
 } PcPsuOutput;
 
+typedef struct StPowerConsumptionInfo {
+    float Gun1_Consumption;
+    float Gun2_Consumption;
+    float Gun3_Consumption;
+    float Gun4_Consumption;
+} PowerConsumptionValue;
+
+typedef struct StPowConsumValue {
+    uint32_t Gun1_Consumption;
+    uint32_t Gun2_Consumption;
+    uint32_t Gun3_Consumption;
+    uint32_t Gun4_Consumption;
+} PowConsumValue;
+
+typedef struct StGunInfo {
+    int ConnectorID;
+    char ReceiptInfo[255];
+    int finalcost_flag;
+    time_t EVLoseTimer;
+    uint8_t EVLoseFlag;
+    char ReservationID[32];
+    uint8_t ReservationStatus;
+    char UserPriceString[255];
+    float PowerConsumption;
+    time_t RecordEnergyTime;
+    char ChargeStartTime[32];
+    char ChargeStopTime[32];
+    char ChargeDuration[32];
+    uint8_t withChiller;      //是否有水冷機
+} GunInfo;
+
+typedef struct Psu_VersionInfo{
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PsuVerInfo;
+
+enum _LCM_UPGRADE_RESULT {
+    _LCM_UPGRADE_RESULT_WAIT = 0,
+    _LCM_UPGRADE_RESULT_PASS,
+    _LCM_UPGRADE_RESULT_FAIL,
+};
+
+typedef struct stTransInfo
+{
+	unsigned char TransDate[6];	//交易日期
+	unsigned char TransTime[6];	//交易時間
+	unsigned char ROC[12];		//EDC簽單調閱編號 (左靠右補空白)
+	unsigned char ApprovalNo[9];		//授權碼[信用卡退貨交易] (左靠右補空白)
+	unsigned char StoreId[18];		//櫃號,機號,發票號碼(左靠右補空白)
+	unsigned char RRN[12];		//信用卡交易序號
+	unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+	unsigned char TransAmount[12];		//交易金額
+	unsigned char VemData[64];		//無人自助設備交易資訊 交易別31/32 (預授權完成/預授權取消) 必要欄位 資訊來源為交易別13 (預授權)的回傳
+}TransInfo;
+
+typedef struct stRecordTransactionInfo
+{
+	int TransactionId;
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    unsigned char ApprovalNo[9];
+    unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+    unsigned char VemData[64];
+    float Amount;
+    unsigned char IsUpload; // 0: not upload, 1: uploaded
+    unsigned char res;
+}RecordTransactionInfo;
+
 typedef struct StDcCommonInfo {
     uint8_t RebootCount;
     uint8_t CcsVersion;
@@ -382,6 +477,17 @@ typedef struct StDcCommonInfo {
     uint8_t chillerCtrl;
     uint8_t debugflag;
     uint8_t LcmFwVersion;
+    int TZOffset;
+    uint8_t AuthroizeType; // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
+    char QRCodeString[255];
+    char DefaultPriceString[255];
+    PowerConsumptionValue pConsumption;
+    int WeatherID;
+    float Temperature;
+    int Location;
+    GunInfo pGunInfo[2];
+    uint8_t showNetPackage;
+    uint8_t showCanPackage;
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 113 - 1
EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.c

@@ -14,7 +14,7 @@
 
 //------------------------------------------------------------------------------
 static sqlite3 *localDb;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 //===============================================
 // SQLite3 related routine
@@ -59,6 +59,11 @@ int DB_Open(void)
                             "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, "
                             "`rebootDatetime` TEXT NOT NULL, unique(rebootDatetime) on conflict replace);";
 
+    char *createPowerConsumption = "CREATE TABLE IF NOT EXISTS power_consumption( "
+                         "idx INTEGER PRIMARY KEY AUTOINCREMENT, "
+                         "connector TEXT, "
+                         "val TEXT);";
+
     if (sqlite3_open(DB_FILE, &localDb)) {
         result = FAIL;
         log_info( "Can't open database: %s", sqlite3_errmsg(localDb));
@@ -88,6 +93,14 @@ int DB_Open(void)
             log_info( "Opened local record table successfully");
         }
 
+        //DS60-120
+        if (sqlite3_exec(localDb, createPowerConsumption, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Create power consumption record table error message: %s", errMsg);
+        } else {
+            log_info("Opened power consumption record table successfully");
+        }
+
         if (sqlite3_exec(localDb, createrebootSql, 0, 0, &errMsg) != SQLITE_OK) {
             result = FAIL;
             log_info( "Create reboot record table error message: %s", errMsg);
@@ -99,6 +112,7 @@ int DB_Open(void)
         sqlite3_close(localDb);
     }
 
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     return result;
 }
 
@@ -222,6 +236,104 @@ int DB_Get_Operactive(uint8_t gunIndex)
     return result;
 }
 
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully (%f).", energy);
+        sprintf(sqlStr,"insert into power_consumption (connector, val) values (%d, %f);",
+            gunIndex,
+            energy); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Insert power consumption error message: %s", errMsg);
+        } else {
+            log_info("Insert connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully.");
+        sprintf(sqlStr,"update power_consumption set val = %f where connector = %d; ",
+                        energy,
+                        gunIndex); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("update config error message: %s", errMsg);
+        } else {
+            //log_info("update connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Get_PowerConsumption(uint8_t gunIndex)
+{
+    uint8_t result = true;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    char** rs;
+    int  rows, cols;
+
+    //sprintf(sqlStr, "select * from config where IsAvailable='IsAvailable' and connector=%d;", gunIndex);
+    sprintf(sqlStr, "select * from power_consumption where connector=%d;", gunIndex); //DS60-120 add
+    //DEBUG_INFO("sqlStr= %s", sqlStr);
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        log_info("Local config query database open successfully.");
+        sqlite3_get_table(localDb, sqlStr, &rs, &rows, &cols, &errMsg);
+        if (rows > 0) {
+            for (int idxRow = 1; idxRow <= rows; idxRow++) {
+                ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = atof(rs[(idxRow * cols) + 2]);
+                log_info("Query connector-%d PowerConsumption: %s", gunIndex, rs[(idxRow * cols) + 2]);
+                
+            }
+        } else {
+            log_info("Query connector-%d fail, set default value to operactive.", gunIndex);
+            result = false;
+        }
+
+        sqlite3_free_table(rs);
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+
 int DB_Reboot_Record(void)
 {
     int result = PASS;

+ 3 - 1
EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.h

@@ -10,5 +10,7 @@ int DB_Reboot_Record(void);
 //for Module_EventLog
 int CreateEventRecord(void);
 int InsertEventRecord(uint8_t *statusCode);
-
+int DB_Get_PowerConsumption(uint8_t gunIndex);
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy);
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy);
 #endif /* _DATA_BASE_H_ */

+ 5 - 5
EVSE/Projects/DD360Audi/Apps/Define/define.c

@@ -236,11 +236,11 @@ char AlarmStatusCode[160][6]=
 "012324", // Connector 1 detects abnormal voltage on the output line
 "012325", // Connector 2 detects abnormal voltage on the output line
 "012326", // System task is lost
-"012327", // DC input ovp
+"012327",   // DC input ovp
 "012328",   // DC input uvp
-"012329",   // reserved
-"012330",   // reserved
-"012331",   // reserved
+"012329",   // Psu Can Communication Fault
+"012330",   // Psu Dc to Dc OTP
+"012331",   // Psu Dc to Dc OVP
 "012332",   // reserved
 "012333",   // reserved
 "012334",   // reserved
@@ -255,7 +255,7 @@ char AlarmStatusCode[160][6]=
 "012343",   // reserved
 "012344",   // AC: Meter IC communication timeout
 "012345",   // AC: Pilot negative error
-"012346",   // reserved
+"012346",   // Psu Communication error with CSU
 "012347",   // reserved
 "012348",   // reserved
 "012349",   // reserved

+ 110 - 65
EVSE/Projects/DD360Audi/Apps/Define/define.h

@@ -186,6 +186,8 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 #define ShmLedBdKey				1011
 #define ShmOcpp20ModuleKey		1012
 #define ShmRelay2BdKey			1013
+#define ShmYesCustomKey         1014
+#define ShmOcppPHModuleKey      1015
 
 #define FaultCodeLength         5
 #define AlarmCodeLength         20
@@ -321,8 +323,15 @@ enum CoreProfile {
      TimeOffsetNextTransition,
      SystemUptimeSec,
      FreeVend,
+     FreeVendIdtag,
      OcppServer,
      MaintainServer,
+     StatusNotificationPeriodically,
+     StatusNotificationInterval,
+     PreAuthAmount,
+     isEnableLocalPowerSharing,
+     PowerSharingServerIP,
+     EVCCID_PREFIX,
      ConfigurationVersion,
 	 _CoreProfile_CNT
 };
@@ -336,10 +345,11 @@ enum OCPP_START_ID_TYPE {
     IdTokenType_Central=0,
     IdTokenType_eMAID,
     IdTokenType_ISO14443,
+    IdTokenType_ISO15693,
     IdTokenType_KeyCode,
     IdTokenType_Local,
-    IdTokenType_NoAuthorization,
-    IdTokenType_ISO15693
+    IdTokenType_MacAddress,
+    IdTokenType_NoAuthorization
 };
 /**************************************************************************************/
 /****structure SysConfigData => shall store the data to NAND flash****************/
@@ -414,8 +424,16 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_NOUSE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct LCD_OVERRIDE
 {
+    unsigned char           connectorId;                // LCD override connector id
     unsigned char           page_index;                 // LCD override page index
     unsigned char           duration;                   // LCD override duration
     unsigned char           isOverideReq:1;             // LCD override request
@@ -448,7 +466,7 @@ struct TTIA
 
 struct LocalSharingInfo
 {
-    unsigned short      AvailableShargingCurrent;       // 0 ~ rating value amp,  Synchronize from local sharing server
+    unsigned short      AvailableShargingCurrent[4];    // 0 ~ rating value amp,  Synchronize from local sharing server
     unsigned char       isConnectedSharingServer:1;     // 0: Disconnected, 1: Connected
 };
 
@@ -464,7 +482,9 @@ typedef union
         unsigned int HardResetStop:1;               // 0: no effect,    1: hard reset stop
         unsigned int SoftResetStop:1;               // 0: no effect,    1: soft reset stop
         unsigned int InvalidIdStop:1;               // 0: no effect,    1: invalid stop when StopTransactionOnInvalidId is true
-        unsigned int res:25;
+        unsigned int RemoteStop:1;                  // 0: no effect,    1: remote stop
+        unsigned int UnlockStop:1;                  // 0: no effect,    1: unlock stop
+        unsigned int res:23;
     }bits;
 }ChargingStop;
 
@@ -557,9 +577,9 @@ struct SysConfigData
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
-	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
+	unsigned char           isEnableLocalPowerSharing;  //0: Disable power sharing  1: Master   2: Slave
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
-    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
+    struct LCD_NOUSE        Legacy_LcdOveride;          // LCD override info (no use anymore)
     struct TTIA             TTIA_Info;                  // TTIA configuration struct
 
     /************PowerCabinet************/
@@ -570,6 +590,7 @@ struct SysConfigData
     unsigned char           MaintainServerURL[512];             // ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
     unsigned char           MaintainServerSecurityProfile;      // Maintain server security profile 0~3
     unsigned char           MaintainServerSecurityPassword[41]; // Maintain server AuthorizationKey for security profile
+    unsigned char           PowerSharingServerIP[512];          // Local power sharing server ip address
 };
 
 struct ChargingInfoData
@@ -609,7 +630,7 @@ struct ChargingInfoData
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
 	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
-	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MaxAddress   7: NoAuthorization
+	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
@@ -685,7 +706,7 @@ typedef struct
     unsigned char       AuthType;                       // 0: _AuthType_None,   1: _AuthType_RFID, 2: _AuthType_RemoteStart
     unsigned char       AuthResult;                     // 0: _AuthResult_None, 1: _AuthResult_Valid,   2: _AuthResult_Invalid
     unsigned char       AuthRequest;                    // 0: no request, 1: authorize request
-    unsigned char       res;
+    unsigned char       AuthIdType;
 }AuthorizingInfoData;
 
 typedef union
@@ -699,26 +720,12 @@ typedef union
         unsigned int MiscNeedAnnouncement:1;            // 0: no need,      1: need send misc command
         unsigned int NeedDispenserVerInfo:1;            // 0: no need,      1: need dispenser to report it's version info
         unsigned int AuthorizeRequest:1;                // 0: idle,         1: requesting                           ( dispenser -> cabinet)
-        unsigned int ConnectorTimeoutConfigRequest:1;   // 0: no request,   1: connector timeout setting            (    ocpp   -> cabinet -> dispenser)
-        unsigned int DefaultPriceConfigRequest:1;       // 0: no request,   1: default price setting                (    ocpp   -> cabinet -> dispenser)
-        unsigned int CurrencyConfigRequest:1;           // 0: no request,   1: currency setting                     (    ocpp   -> cabinet -> dispenser)
-        unsigned int HardwareRebootRequest:1;           // 0: no request,   1: hardware reboot request              (    ocpp   -> cabinet -> dispenser)
         unsigned int HardwareRebootConfirm:1;           // 0: no effect,    1: dispenser confirmed
-        unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
         unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
         unsigned int FirmwareUpdateRequest:1;           // firmware update request
         unsigned int FirmwareUpdateConfirm:1;           // firmware update start
         unsigned int FirmwareUpdateCompleted:1;         // firmware update completed
-        unsigned int BackendStatusRequest:1;            // 0: no request,   1: backend connection status has changed            ( cabinet -> dispenser)
-        unsigned int EthernetStatusRequest:1;           // 0: no request,   1: ethernet connection status has changed           ( cabinet -> dispenser)
-        unsigned int WiFiStatusRequest:1;               // 0: no request,   1: wifi connection status has changed               ( cabinet -> dispenser)
-        unsigned int TelcomModemStatusRequest:1;        // 0: no request,   1: 4g connection status has changed                 ( cabinet -> dispenser)
-        unsigned int BillingStatusRequest:1;            // 0: no request,   1: billing status has changed                       ( cabinet -> dispenser)
-        unsigned int StopButtonStatusRequest:1;         // 0: no request,   1: stop charging button status has changed          ( cabinet -> dispenser)
-        unsigned int AuthModeConfigRequest:1;           // 0: no request,   1: AuthMode Config has changed                      ( cabinet -> dispenser)
-        unsigned int EVCCIDConfigRequest:1;             // 0: no request,   1: EVCCID Config has changed                        ( cabinet -> dispenser)
-        unsigned int LEDIntensityRequest:1;             // 0: no request,   1: LED Intensity has changed                        ( cabinet -> dispenser)
-        unsigned int res:7;
+        unsigned int res:21;
     }bits;
 }DispenserSettingFlag;
 
@@ -735,7 +742,7 @@ struct DispenserModule
     unsigned char   RfidCardNumEndian;          //0: little endian,  1: big endian
     unsigned char   isAPP;                      //for AuthorisationMode=0; 0:false, 1:true
     unsigned char   isQRCode;                   //for AuthorisationMode=0; 0:false, 1:true
-    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true
+    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true; for Noodoe Credit Card +2^1:true
     unsigned char   QRCodeMadeMode;             //for isQRCode=1 ; 0: default	1:customized
     unsigned char   QRCodeContent[128];         //for QRCodeMadeMode=1
 
@@ -794,10 +801,6 @@ struct DispenserInfoData
     }CheckInLog;                                                        // record dispenser checkin status
     unsigned char               ConnectorLog[GENERAL_GUN_QUANTITY];     // record connector quantity of dispenser
     struct ConnectionInfoData   ConnectionInfo[GENERAL_GUN_QUANTITY];
-
-    unsigned short      ConnectorTimeout;           // connector plug in timeout, unit 1s
-    unsigned int        DefaultPrice;               // dispenser default price, unit: 0.01 (dollar/kWh)
-    unsigned char       Currency;                   // dispenser currency index
 };
 
 struct WARNING_CODE_INFO
@@ -815,16 +818,11 @@ typedef union
     struct
     {
         unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging                   ( dispenser -> cabinet)
-        unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStartConfirm:1;
-        unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStopConfirm:1;
-        unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  UnlockStopConfirm:1;
         unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop                           ( dispenser -> cabinet)
         unsigned int  PsuReleasable:1;
-        unsigned int  AvailabilityRequest:1;            // 0: no request,    1: change availability                             (    ocpp   -> cabinet -> dispenser)
-        unsigned int  AccountBalanceRequest:1;          // 0: no request,    1: set account balance                             (    ocpp   -> cabinet -> dispenser)
         unsigned int  AnnounceBalance:1;                //
         unsigned int  StartWaitPlug:1;                  //
         unsigned int  NeedCleanAuthorizeInfo:1;         //
@@ -837,7 +835,7 @@ typedef union
         unsigned int  Disconnection:1;
         unsigned int  GfdDetection:1;                   // 0: stop,         1: start
         unsigned int  GetStartChargingSoc:1;            // 0: no effect,    1: get start soc
-        unsigned int  res:8;
+        unsigned int  res:13;
     }bits;
 }ConnectorParameter;
 
@@ -874,9 +872,12 @@ struct ConnectorInfoData
     float                   CapabilityCurrent;              // unit 0.1A
     float                   CapabilityPower;                // unit 0.1kW
 
-    unsigned int            UserPrice;                      // connector user's user price, unit: 0.01 (dollar / kWh)
-    unsigned int            TotalCost;                      // connector user's total cost, unit: 0.01 dollar
-    int                     AccountBalance;                 // connector user's account balance, unit: 0.01 dollar
+    float                   UserPrice;                      // connector user's user price, unit: 1 (dollar / kWh)
+    float                   TotalCost;                      // connector user's total cost, unit: 1 dollar
+    float                   AccountBalance;                 // connector user's account balance, unit: 1 dollar
+    float                   CostDiscount;                   // connector user's Discount or couponPoint, unit: 1 point
+    float                   EnergyCost;                     // connector user's energy cost, unit: 1 dollar
+    float                   ParkingFee;                     // connector user's parking fee, unit: 1 dollar
 };
 
 typedef union
@@ -892,23 +893,6 @@ typedef union
     }bits;
 }CabinetSettingFlag;
 
-typedef struct
-{
-    unsigned int ConnectionTimeout;             // unit: 1s
-    unsigned int DefaultPrice;                  // unit: 0.01dollar
-    unsigned int Currency;                      // currency index
-    unsigned int BackendStatus;                 // 0: disable, 1: connected, 2: disconnected
-    unsigned int EthernetStatus;                // 0: disable, 1: connected, 2: disconnected
-    unsigned int WiFiStatus;                    // 0: disable, 1: connected, 2: disconnected
-    unsigned int TelcomModemStatus;             // 0: disable, 1: connected, 2: disconnected
-    unsigned int BillingStatus;                 // 0: disable, 1: enable
-    unsigned int StopChargingButton;            // 0: disable, 1: enable
-    unsigned int HardwareReboot;                // 1: HardwareReboot, Other value: no effect
-    unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
-    unsigned int AuthModeConfig;                // 0: enable,  1: disable
-    unsigned int EVCCIDConfig;                  // 0: disable, 1: enable
-}CabinetMiscCommand;
-
 typedef struct DC_METER_INFO
 {
     double presetVoltage;                       // resolution: 1.000v
@@ -1011,11 +995,11 @@ struct SysInfoData
     unsigned char           AuthorizedType;             // record authorized type
     unsigned char           AuthorizedStatus;           // cabinet authorized status
     CabinetSettingFlag      CabinetSetting;
-    CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
     DC_Meter_Info DcMeterInfo[4];
     unsigned char           OTPTemp;                    // OTP Temperature
     unsigned char           OTPTempR;                   // OTP Recovery Temperature
+    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info (no use anymore)
 };
 
 struct SysConfigAndInfo
@@ -1334,9 +1318,9 @@ char AlarmStatusCode[160][6]=
     "012326",   // System task is lost
     "012327",   // DC input ovp
     "012328",   // DC input uvp
-    "012329",   // reserved
-    "012330",   // reserved
-    "012331",   // reserved
+    "012329",   // Psu Can Communication Fault
+    "012330",   // Psu Dc to Dc OTP
+    "012331",   // Psu Dc to Dc OVP
     "012332",   // reserved
     "012333",   // reserved
     "012334",   // reserved
@@ -1351,7 +1335,7 @@ char AlarmStatusCode[160][6]=
     "012343",   // reserved
     "012344",   // AC: Meter IC communication timeout
     "012345",   // AC: Pilot negative error
-    "012346",   // reserved
+    "012346",   // Psu Communication error with CSU
     "012347",   // reserved
     "012348",   // reserved
     "012349",   // reserved
@@ -1521,13 +1505,17 @@ struct AlarmCodeData
             unsigned char DcInputOVP:1;                             //bit 7
             //AlarmVal[16]
             unsigned char DcInputUVP:1;                             //bit 0
-            unsigned char :7;                                       //reserved bit 1 ~ bit 7
+            unsigned char PsuCanCommFault:1;                        //bit 1
+            unsigned char PsuDcDcOtp:1;                             //bit 2
+            unsigned char PsuDcDcOvp:1;                             //bit 3
+            unsigned char :4;                                       //reserved bit 4 ~ bit 7
             //AlarmVal[17]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
             //AlarmVal[18]
             unsigned char MeterIcCommTimeout:1;                     //bit 0
             unsigned char PilotNegativeError:1;                     //bit 1
-            unsigned char :6;                                       //reserved bit 2 ~ bit 7
+            unsigned char PsuComminicationErrWithCSU:1;             //bit 2
+            unsigned char :5;                                       //reserved bit 3 ~ bit 7
             //AlarmVal[19]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
 		}bits;
@@ -2312,6 +2300,7 @@ struct PsuData
 	unsigned char           GroupCount;
 	unsigned char           Work_Step;
 	struct PsuModuleVer     PsuVersion[MAX_PSU_QUANTITY];
+	unsigned char           PsuStopChargeFlag;
 };
 
 /************************************************************************************/
@@ -4429,7 +4418,7 @@ struct OCPP16ConfigurationTable
 struct StrcutSetUserPrice
 {
     unsigned char   idToken[21];
-    unsigned char   price[256];
+    unsigned char   price[1024];
 };
 
 struct ChargingPrice
@@ -4473,13 +4462,13 @@ struct StrcutRunningCost
     struct IdlePrice        idlePrice;              // (optional) Price components while not charging. Optional if no idle fee is charged.
     struct NextPeriod       nextPeriod;             // (optional) Pricing for next period
     struct Triggers         triggerMeterValue;      // (optional) Triggers to request a new meter value. Optional if no idle fee charged.
-    unsigned char           description[256];       // Compatible California pricing V1.0
+    unsigned char           description[1024];      // Compatible California pricing V1.0
 };
 
 struct StrcutFinalCost
 {
     int             txId;
-    unsigned char   description[256];
+    unsigned char   description[1024];
 };
 
 struct StructCost
@@ -4598,6 +4587,58 @@ struct StructSessionTarget
     unsigned short      targetDuration;     // Unit: Minutes    0 is unlimit
 };
 
+//===================================
+// YES custom protocol
+//===================================
+struct StructChargerInfo
+{
+    unsigned char station_name[64];
+};
+
+struct StructWeatherInfo
+{
+    int   weatherId;
+    float temperature;
+};
+
+struct StructCreditDeductResult
+{
+    int txId;
+    unsigned char creditNo[64];
+    unsigned char vemData[80];
+    unsigned char ROC[20];
+    unsigned char RRN[20];
+    unsigned char storeId[20];
+    unsigned char approvalNo[20];
+    double        amount;
+    unsigned char deductResult:1;
+    unsigned char isDonateInvoice:1;
+};
+
+struct StructReaderStatus
+{
+    int readerStatus;
+    unsigned char creditNo[64];
+    unsigned char ReportReaderStatusReq:1;
+};
+
+struct StructTcciCustomData
+{
+    struct StructChargerInfo ChargerInfo;
+    struct StructWeatherInfo WeatherInfo;
+    struct StructCreditDeductResult DeductInfo;
+    struct StructReaderStatus ReaderStatus[CONNECTOR_QUANTITY];
+    unsigned char TriggerReaderReq[3];
+    unsigned char SerialNo[CONNECTOR_QUANTITY][37];
+    unsigned char VEMData[CONNECTOR_QUANTITY][65];
+
+    unsigned char ReportCreditDeductReq:1;
+    unsigned char ChargerInfoReq:1;
+    unsigned char ChargerInfoConf:1;
+    unsigned char WeatherInfoReq:1;
+    unsigned char WeatherInfoConf:1;
+};
+
 struct OCPP16Data
 {
     unsigned char                           OcppServerURL[512];     //http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
@@ -4787,6 +4828,7 @@ struct OCPP16Data
     struct StructSignCertificate                    SignCertificate;
     struct StructSignedFirmwareStatusNotification   SignedFirmwareStatusNotification;
     struct StructSessionTarget                      SessionTarget[CONNECTOR_QUANTITY];
+    struct StructTcciCustomData                     TcciCustomData;
 };
 
 
@@ -4831,6 +4873,7 @@ enum OCPP20CtrlrVariable
 	ChargingStation_SupplyPhases,
 	ChargingStation_SystemUptimeSec,
 	ChargingStation_FreeVend,
+	ChargingStation_FreeVendIdtag,
 	Connector_Available,
 	Connector_ConnectorType,
 	Connector_SupplyPhases,
@@ -4879,6 +4922,8 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_WebSocketPingInterval,
 	OCPPCommCtrlr_ResetRetries,
 	OCPPCommCtrlr_PublicKeyWithSignedMeterValue,
+    OCPPCommCtrlr_StatusNotificationPeriodically,
+    OCPPCommCtrlr_StatusNotificationInterval,
     OCPPCommCtrlr_VariableVersion,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
@@ -5099,7 +5144,7 @@ struct ChargingScheduleType
 
 struct ChargingProfileType
 {
-	unsigned short int id;											// Required. Id of ChargingProfile.
+	int id;											                // Required. Id of ChargingProfile.
 	unsigned short int stackLevel;									// Required. Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
 	unsigned char chargingProfilePurpose[36];						// Required. Defines the purpose of the schedule transferred by this profile
 	unsigned char chargingProfileKind[16];							// Required. Indicates the kind of schedule.

+ 1 - 15
EVSE/Projects/DD360Audi/Apps/Makefile

@@ -113,12 +113,6 @@ CHKSYSTASK_SRC_FILES = $(patsubst %.o, %.c, $(CHKSYSTASK_OBJ_FILES))
 %.o: %.c
 	$(CC) $(CFLAGS) -c $<
 
-#Simulation
-SIMULATION_OBJ_FILES = $(COMMON_OBJ_FILES) simulation.o
-SIMULATION_SRC_FILES = $(patsubst %.o, %.c, $(SIMULATION_OBJ_FILES))
-%.o: %.c
-	$(CC) $(CFLAGS) -c $<
-
 #Event Log
 EVENTLOG_OBJ_FILES = $(COMMON_OBJ_FILES) $(DataBaseLib)/DataBase.o \
 						$(EventLogLib)/Module_EventLogging.o
@@ -148,7 +142,7 @@ all: CopyFile apps
 apps: MainTask DoCommTask EvCommTask UpdateFWTask ChkSysTask \
 		EventLoggingTask InternalCommTask LcmControlTask \
 			PrimaryCommTask ReadCmdlineTask UnsafetyOutputTool \
-				SimulationApp FactoryConfigApp OtherTools CleanExec
+				FactoryConfigApp OtherTools CleanExec
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
@@ -180,11 +174,6 @@ ChkSysTask:
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o Module_ChkSysTask.o $(ChkSysTaskLib)/Module_ChkSysTask.c
 	#$(CC) -o Module_ChkSysTask Module_ChkSysTask.o 
 
-SimulationApp:
-	$(CC) $(DEFINE) $(SIMULATION_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) -o simulation 
-	#$(CC) $(DEFINE) $(CFLAGS) -c -o simulation.o simulation.c
-	#$(CC) -o simulation simulation.o
-
 EventLoggingTask:
 	$(CC) $(DEFINE) $(EVENTLOG_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(Lib_SQLite3) -o Module_EventLogging
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o define.o $(DefineLib)/define.c
@@ -242,7 +231,6 @@ OtherTools:
 	cp -f Module_EvComm $(RootPath)
 	cp -f Module_UpdateFW $(RootPath)
 	cp -f Module_ChkSysTask $(RootPath)
-	cp -f simulation $(RootPath)
 	cp -f Module_EventLogging $(RootPath)
 	cp -f Module_InternalComm $(RootPath)
 	cp -f Module_LcmControl $(RootPath)
@@ -262,7 +250,6 @@ OtherTools:
 	cp -f Module_EvComm $(OutputPath)
 	cp -f Module_UpdateFW $(OutputPath)
 	cp -f Module_ChkSysTask $(OutputPath)
-	cp -f simulation $(OutputPath)
 	cp -f Module_EventLogging $(OutputPath)
 	cp -f Module_InternalComm $(OutputPath)
 	cp -f Module_LcmControl $(OutputPath)
@@ -282,7 +269,6 @@ CleanExec:
 	rm Module_EvComm
 	rm Module_UpdateFW
 	rm Module_ChkSysTask
-	rm simulation 
 	rm Module_EventLogging
 	rm Module_InternalComm
 	rm Module_LcmControl

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 804 - 60
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c


+ 120 - 3
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h

@@ -16,7 +16,7 @@
 #define TFTP_PULL_CMD                           "tftp"
 #define SIGTERM_MSG                             "SegmentFault.~~~~\n"
 
-#define MAX_REGISTER_NUM                        30
+#define MAX_REGISTER_NUM                        50
 
 #define CHECK_NETWORK_FAIL_COUNT                10//10
 #define CONNECT_SERVER_FAIL_COUNT               3//5
@@ -80,6 +80,25 @@
 #define REG_QRCODE_URL_INFO                     0X10
 #define REG_WAIT_PLUG_IT_STATE                  0x11
 #define REG_Ground_Fault_Detection              0x12
+#define REG_CABINET_DCM_VERSION                 0x13
+#define REG_CABINET_OTHER_VERSION               0x14
+#define REG_TOTAL_PSU_QUANTITY                  0x15
+#define REG_PSU_VERSION                         0x16
+#define REG_RESERVATION_IDTAG                   0x17
+#define REG_DISPENSER_REQUEST                   0x18
+#define REG_REMOTE_START_NO_ID                  0x19
+#define REG_REFUND_AMOUNT                       0x1A
+#define REG_PREPAYMENT_INFO                     0x1B
+#define REG_PAYMENT_FAIL_REASON                 0x1C
+#define REG_CONNECTOR_QR_CODE                   0x1D
+#define REG_STATION_INFO                        0x1E
+#define REG_DEDUCT_INFO                         0x1F
+#define REG_READ_CABINET_SYSTEMID               0x20
+#define REG_READ_DEFAULT_PRICE                  0x21
+#define REG_READ_USER_PRICE                     0x22
+#define REG_RECEIPT_INFO                        0x23
+#define REG_POWER_CONSUMPTION_INFO              0x24
+#define REG_READ_CHARGING_TIMESTAMP             0x25
 
 //------------------------------------------------------------------------------
 //--- dispenser result ---
@@ -111,19 +130,90 @@
 #define MISC_CMD_WEB_STOP_CHARGING              (0x000B)
 #define MISC_CMD_AUTH_DISABLE					(0x000C)
 #define MISC_CMD_EVCCID_ENABLE					(0x000D)
+#define MISC_CMD_LED_INTENSITY                  (0x000E)
+#define MISC_CMD_AC_CONTACTOR                   (0x000F)
+#define MISC_CMD_TIME_OFFSET                    (0x0010)
 
 #define MISC_CMD_HARDWARE_REBOOT                (0x0101)
 #define MISC_CMD_SOFTWARE_RESTART               (0x0102)
 #define MISC_CMD_REMOTE_START_CHARGING          (0x0103)
 #define MISC_CMD_REMOTE_STOP_CHARGING           (0x0104)
 #define MISC_CMD_REMOTE_UNLOCK                  (0x0105)
+#define MISC_CMD_RESERVATION                    (0x0106)
+#define MISC_CMD_CHANGE_LCM_PAGE                (0x0107)
+#define MISC_CMD_QR_CODE_REQ                    (0x0108)
+#define MISC_CMD_STATION_INFO_REQ               (0x0109)
+#define MISC_CMD_FINAL_COST_REQ                 (0x010A)
+#define MISC_CMD_LINE_STATUS_REQ                (0x010B)
+#define MISC_CMD_DEFAULT_PRICE_REQ              (0x010C)
+#define MISC_CMD_USER_PRICE_REQ                 (0x010D)
+#define MISC_CMD_RECEIPT_REQ                    (0x010E)
 
 #define ST_UPDATE_FIRMWARE                      (0x01)
 #define ST_NO_UPDATE_FIRMWARE                   (0x02)
 
+#define LCM_PAGE_REMOTE_START_NO_ID             (0x0001)
+#define DISPENSER_REQ_CHARGING_CANCEL           (0x0001)
+
+#define UPLOAD_DEDUCT_DB						(0x5656)
+
+
 //------------------------------------------------------------------------------
 #pragma pack(push)
 #pragma pack(1)
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ChargingCancel : 1; // 0: no effect, 1: charging cancel request
+        unsigned int res : 31;
+    }bits;
+} ConnectorActReqVar;
+
+typedef struct StDeductInfoVar {
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    int TransactionId;								// transaction id
+    int Amount;                                     // unit = 0.01 dollar
+    char ApprovalNumber[12];						// approval number
+} DeductInfoVar;
+
+/*
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int JoinLine:1;                    // 0: no effect,                1: JoinLine page is trigger
+        unsigned int PaymentSwitch:1;               // 0: no effect,                1: PaymentSwitch page is trigger
+        unsigned int res:30;
+    }bits;
+} ChangePageReq;
+*/
+
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ReservationReq:1;              // 0: no effect,                1: need to request Reservation
+        unsigned int RemoteStartNoID:1;             // 0: no effect,                1: need to request RemoteStartNoID
+        unsigned int StationInfoReq:1;              // 0: no effect,                1: need to request StationInfo
+        unsigned int FinalCostReq:1;                // 0: no effect,                1: need to request FinalCost
+        unsigned int DefaultPriceReq : 1;           // 0: no effect,                1: need to request Default price
+        unsigned int UserPriceReq : 1;              // 0: no effect,                1: need to request User price
+        unsigned int ReceiptReq : 1;                // 0: no effect,                1: need to request Receipt
+        unsigned int res:27;
+    }bits;
+} MoreInfoReq;
+
+typedef struct StStationVar {
+    int StationID;
+    char StationName[64];
+    int WeatherID;
+    float Temperature;
+} StationVar;
 
 typedef struct StConnectorState {
     uint8_t State;
@@ -131,7 +221,8 @@ typedef struct StConnectorState {
     uint8_t ConnectorTemp;
     uint8_t ChillerTemp;
     uint8_t PlugIn;
-    uint8_t Reserved[2];
+    uint32_t consumption;
+    uint8_t Reserved[1];
 } ConnectorState;
 
 typedef struct StConnectorIDTable {
@@ -232,9 +323,35 @@ typedef struct StAccountInfo {
     int UserPrices;
     int TotalCost;
     int Balance;
-    uint8_t Reserved[3];
+    int Discount;
+    int Transaction;
+    int EnergyCost;
+    int ParkingFee;
+    uint32_t RemainAmount;
+    uint8_t Reserved[1];
 } AccountInfo;
 
+typedef struct stCabinetDCMVersion {
+    uint8_t CabinetModelName[32];
+    uint8_t CabinetBoolLoaderVersion[32];
+    uint8_t CabinetKernelVersion[32];
+    uint8_t CabinetRFSystemVersion[32];
+    uint8_t CabinetPrimaryVersion[32];
+    uint8_t CabinetIPAddr[32];
+}PCDCMVer;
+
+typedef struct stCabinetOtherVersion {
+    uint8_t CabinetRelay0Version[32];
+    uint8_t CabinetRelay1Version[32];
+    uint8_t CabinetFanVersion[32];
+}PCOthVer;
+
+typedef struct stCabinetEachPsuVersion {
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PCnPsuVer;
+
 #pragma pack(pop)
 
 #endif /* _DO_COMM_H_ */

+ 14 - 2
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Ev_Comm.c

@@ -13,7 +13,7 @@
 
 #include "Ev_Comm.h"
 #include "Module_EvComm.h"
-
+#include "../Config.h"
 //------------------------------------------------------------------------------
 int PackageIdCmd(int cmd)
 {
@@ -22,14 +22,26 @@ int PackageIdCmd(int cmd)
 
 void SendCmdToEvboard(int cmd, uint8_t *data, uint8_t dataLen)
 {
+    DcCommonInfo* ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     int fd = GetCanFd();
     struct can_frame frame;
-
+    int i;
+    int len = 0;
+    char _info[1024];
     frame.can_id = cmd;
     frame.can_dlc = dataLen;
     memcpy(frame.data, data, sizeof(frame.data));
 
     write(fd, &frame, sizeof(struct can_frame));
+
+    if (ShmDcCommonData->showCanPackage) {
+        len += sprintf(&_info[len], "CAN Dispenser => EV Tx:\t[0x%X] ", cmd);
+        for (i = 0; i < dataLen; i++) {
+            len += sprintf(&_info[len], "%X ", data[i]);
+        }
+        len += sprintf(&_info[len], "\n");
+        printf("%s",_info);
+    }
 }
 
 //------------------------------------------------------------------------------

+ 154 - 43
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -226,6 +226,54 @@ static void AddrAssignment(uint8_t *data)
     //}
 }
 
+void CheckEvConnect(int gunIndex)
+{
+    int isSameType = FALSE;
+    int isDisconnect = FALSE;
+    int gunType = _Type_CCS_2;
+    struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+    struct InfoCodeData* pInfoCode = (struct InfoCodeData*)GetShmInfoCodeData();
+    struct ChargingInfoData* pDcChargingInfo_0 = (struct ChargingInfoData*)GetDcChargingInfoData(0);
+    struct ChargingInfoData* pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(1);
+
+    if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) {
+        isSameType = TRUE;
+        isDisconnect = ShmDcCommonData->pGunInfo[0].EVLoseFlag | ShmDcCommonData->pGunInfo[1].EVLoseFlag;
+        gunType = pDcChargingInfo_0->Type;
+    } else {
+        isDisconnect = ShmDcCommonData->pGunInfo[gunIndex].EVLoseFlag;
+        gunType = pDcChargingInfo->Type;
+    }
+
+    //log_info("ShmDcCommonData->EVDisconnectFlag[%d]:%d", gunIndex, ShmDcCommonData->EVDisconnectFlag[gunIndex]);
+    if (isDisconnect) {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = YES;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = YES;
+            break;
+        }
+
+    } else {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = NO;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = NO;
+            break;
+        }
+    }
+}
+
 void CANReceiver(int fd)
 {
     pid_t canRecPid;
@@ -255,7 +303,11 @@ void CANReceiver(int fd)
         uint8_t lastConnTemp[2] = {0, 0};
         struct can_frame frame;
         ChillerTemp chiilerTemp = {0};
+        time_t CCS_PlugoutTimer[2] = { 0 };
         struct ChargingInfoData *pDcChargingInfo = NULL;
+        int len = 0;
+        char _info[1024];
+        int i;
 
         pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
         pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -269,11 +321,33 @@ void CANReceiver(int fd)
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
 
-        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        ShmDcCommonData->pGunInfo[0].EVLoseTimer = time((time_t*)NULL);
+        ShmDcCommonData->pGunInfo[1].EVLoseTimer = time((time_t*)NULL);
 
+        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        CCS_PlugoutTimer[0] = time((time_t*)NULL);
+        CCS_PlugoutTimer[1] = time((time_t*)NULL);
         while (isContinue) {
             memset(&frame, 0, sizeof(struct can_frame));
 
+            for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
+                pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
+                // 檢查是否有收到EV小板訊號
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[_index].EVLoseTimer > 3) &&
+                    !ShmDcCommonData->pGunInfo[_index].EVLoseFlag &&
+                    pDcChargingInfo->SystemStatus != S_UPDATE && !ShmDcCommonData->debugflag) {
+
+                    ShmDcCommonData->pGunInfo[_index].EVLoseTimer = time((time_t*)NULL);
+                    ShmDcCommonData->pGunInfo[_index].EVLoseFlag = TRUE;
+
+                    system("/sbin/ip link set can0 down");
+                    sleep(1);
+                    system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
+                    system("/sbin/ip link set can0 up");
+                }
+                CheckEvConnect(_index);
+            }
+
             nbytes = read(fd, &frame, sizeof(struct can_frame));
             if (nbytes <= 0) {
                 usleep(10000);
@@ -293,6 +367,16 @@ void CANReceiver(int fd)
             intCmd = (int) (frame.can_id & CAN_EFF_MASK & 0xFFFFFF00);
 
             recvID = ((uint8_t) (frame.can_id & 0x000000FF)); // 0x01 or 0x02
+            
+            if (ShmDcCommonData->showCanPackage) {
+                len = 0;
+                len += sprintf(&_info[len], "CAN Dispenser <= EV Rx:\t[0x%X] ", frame.can_id);
+                for (i = 0; i < nbytes; i++) {
+                    len += sprintf(&_info[len], "%X ", frame.data[i]);
+                }
+                len += sprintf(&_info[len], "\n");
+                printf("%s", _info);
+            }
 
             for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {                    // 假設有找到回應的 Index
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
@@ -325,6 +409,9 @@ void CANReceiver(int fd)
                 usleep(10000);
                 continue;
             }
+            // Reset Connect Timer
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun);
             gunTypeIndex = pDcChargingInfo->type_index;
@@ -341,13 +428,30 @@ void CANReceiver(int fd)
                             pSysInfo->CurGunSelected = targetGun;
 #endif                        
                     } else if (frame.data[0] == UNPLUG) {
-                        log_info("Conn %d, Unplug. ", targetGun);
+                        if (pDcChargingInfo->Type != _Type_CCS_2)
+                            log_info("Conn %d, Unplug. ", targetGun);
                         strcpy( (char *) pDcChargingInfo->EVCCID, "");
                     } else {
                         log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]);
                     }
+                    if(pDcChargingInfo->RemoteStartFlag == YES) {
+                        pSysInfo->CurGunSelected = targetGun;
+                    }
+                }
+                // CCS 小板確認拔除三秒
+                if (pDcChargingInfo->Type == _Type_CCS_2) {
+                    if (frame.data[0] == UNPLUG) {
+                        if ((time((time_t*)NULL) - CCS_PlugoutTimer[targetGun]) > 3) {
+                            if (pDcChargingInfo->ConnectorPlugIn != frame.data[0])
+                                log_info("CCS Conn %d, Unplug. ", targetGun);
+                        } else {
+                            frame.data[0] = PLUG;
+                        }
+                    } else {
+                        CCS_PlugoutTimer[targetGun] = time((time_t*)NULL);
+                        frame.data[0] = PLUG;
+                    }
                 }
-
                 pDcChargingInfo->ConnectorPlugIn = frame.data[0];
                 pDcChargingInfo->PilotVoltage = frame.data[1];
 
@@ -424,6 +528,7 @@ void CANReceiver(int fd)
 
                     if (frame.data[1] > pDcChargingInfo->EvBatterySoc) {
                         pDcChargingInfo->EvBatterySoc = frame.data[1];
+                        log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc);
                     }
                 }
                 //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove
@@ -446,8 +551,8 @@ void CANReceiver(int fd)
                 //printf("RemainChargingDuration = %d",  pDcChargingInfo->RemainChargingDuration);
 
                 if (pDcChargingInfo->Type == _Type_Chademo) {
-                    //if (ShmCHAdeMOData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d CHAdeMO board status = %d ", targetGun, ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus);
                         ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -456,8 +561,8 @@ void CANReceiver(int fd)
                     ShmCHAdeMOData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmCHAdeMOData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //if (ShmGBTData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d GB Board status = %d ", targetGun, ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -466,7 +571,8 @@ void CANReceiver(int fd)
                     ShmGBTData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmGBTData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
+                    if (ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus != frame.data[0] && frame.data[0] != 0xFF) {
+                        log_info("Gun%d CCS board status = %d ", targetGun, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
                 }
@@ -549,20 +655,23 @@ void CANReceiver(int fd)
 
                     pDcChargingInfo->ChillerTemp = maxChillerTemp;
                 }
+                if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
+                    maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
+                    //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
+                    //    printConnTemp = YES;
+                    //}
+                    maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
+                    if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
+                    {
+                        lastConnTemp[targetGun] = maxConnTemp;
+                        printConnTemp = YES;
+                    }
 
-                maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
-                //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
-                //    printConnTemp = YES;
-                //}
-                maxConnTemp = getAvageTemp(maxConnTemp,targetGun);
-                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
-                {
-                    lastConnTemp[targetGun] = maxConnTemp;
-                    printConnTemp = YES;
+                    pDcChargingInfo->ConnectorTemp = maxConnTemp;
+                } else {
+                    //log_info("Connector%d Tmep is zero:[%d,%d]", gunTypeIndex, ShmDcCommonData->ConnectorTemp[gunTypeIndex][0],
+                    //    ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]);
                 }
-
-                pDcChargingInfo->ConnectorTemp = maxConnTemp;
-
                 //紀錄槍頭和水冷機溫度, 在系統狀態變化或溫度大於150
                 if ((ShmDcCommonData->SystemModeChange[targetGun] == YES) ||
                         (printConnTemp == YES) ||
@@ -573,11 +682,13 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d",
+                    log_info("Conn %d max temp = %d, chiller = [%d %d], chiller2 = [%d %d]",
                              targetGun,
-                             maxConnTemp,
-                             chillerTemp[0],
-                             chillerTemp[1]);
+                             pDcChargingInfo->ConnectorTemp,
+                             chiilerTemp.Temp[0],
+                             chiilerTemp.Temp[1],
+                             chiilerTemp.Temp[2],
+                             chiilerTemp.Temp[3]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
@@ -645,25 +756,25 @@ void CANReceiver(int fd)
                 break;
             case ACK_EVCCID_REQ:
 
-                        if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
-                            pDcChargingInfo->Type == _Type_CCS_2)
-                        {
-                            {
-                                memset (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        0,
-                                        sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
-                                memcpy (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        frame.data, frame.can_dlc );
-                            }
-
-                            sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
-                                    frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
-
-                            pDcChargingInfo->EVCCID [17] = '\0';
-                            log_info( "************* Gun %d->EVCCID = %s ************* ", targetGun, pDcChargingInfo->EVCCID );
-                        }
+                if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
+                    pDcChargingInfo->Type == _Type_CCS_2)
+                {
+                    {
+                        memset (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                0,
+                                sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
+                        memcpy (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                frame.data, frame.can_dlc );
+                    }
+
+                    sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
+                            frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
+
+                    pDcChargingInfo->EVCCID [17] = '\0';
+                    log_info( "Gun %d->EVCCID = %s ", targetGun, pDcChargingInfo->EVCCID );
+                }
                 break;
             default:
                 log_info("EV board = %d, Ack none defined. intCmd = %d  ", targetGun, intCmd);

+ 5 - 2
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -1028,7 +1028,7 @@ int main(int argc, char *argv[])
                 //if (waitPsuVolwithRealyVol(gunIndex) == NO) {
                 //    continue;
                 //}
-
+                GetEvBatteryInfo(gunIndex, pDcChargingInfo->Evboard_id); //DS60-120 add
                 // 計算 Power
                 pDcChargingInfo->PresentChargingPower =
                     ((float)((pDcChargingInfo->PresentChargingVoltage) *
@@ -1040,7 +1040,7 @@ int main(int argc, char *argv[])
                     chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                 } else {
                     int passTime = pDcChargingInfo->PresentChargedDuration - chargingTime[gunIndex];
-
+                    
                     if (passTime > 0) {
                         float changingPow = (pDcChargingInfo->PresentChargingPower) * passTime / 3600;
                         if (pSysConfig->BillingData.isBilling) {
@@ -1048,9 +1048,12 @@ int main(int argc, char *argv[])
                         }
 
                         pDcChargingInfo->PresentChargedEnergy += changingPow;
+
+                        ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption += changingPow;
                         pDcChargingInfo->PowerConsumption += changingPow;
                         chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                     }
+                    
                 }
 
                 // 開始確認車端是否同意開始充電

+ 24 - 24
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/FanBoard.c

@@ -20,6 +20,7 @@ static struct SysInfoData *pSysInfo = NULL;
 static struct AlarmCodeData *pAlarmCode = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
+static DcCommonInfo* ShmDcCommonData = NULL;
 
 static int Uart5Fd = 0;
 static struct timeval gFanBoardRunTimer;
@@ -149,8 +150,8 @@ static void GetFanSpeedByFunction(void)
 static void SetRtcData_Fan(void)
 {
     struct timeb csuTime;
-    struct tm *tmCSU;
-    Rtc rtc = {0};
+    struct tm* tmCSU;
+    Rtc rtc = { 0 };
 
     ftime(&csuTime);
     tmCSU = localtime(&csuTime.time);
@@ -186,30 +187,42 @@ static void SetRtcData_Fan(void)
 static void SetModelName_Fan(void)
 {
     if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
-        return;
-    } else
-        log_info("******** Set Model name FAIL = %s ************", pSysConfig->ModelName);
+        log_info("Set Model name PASS = %s ", pSysConfig->ModelName);
+    }
 }
 
 static void GetFwAndHwVersion_Fan(void)
 {
-    Ver ver = {0};
+    Ver ver = { 0 };
 
     if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // FanModuleData
-        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        strcpy((char*)ShmFanModuleData->version, ver.Version_FW);
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleFwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s1 = %s ", ver.Version_FW);
     }
 
     if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleHwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s2 = %s ", ver.Version_HW);
     }
 }
 
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
 static void fanBoardPorcess(void)
 {
     if (ShmFanModuleData->SelfTest_Comp == NO) {
@@ -217,8 +230,8 @@ static void fanBoardPorcess(void)
     }
 
     if (ShmFanModuleData->SelfTest_Comp == YES ||
-            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
-            pSysInfo->FanModuleFwRev[0] != '\0') {
+        strlen((char*)pSysInfo->FanModuleFwRev) != 0 ||
+        pSysInfo->FanModuleFwRev[0] != '\0') {
         ShmFanModuleData->SelfTest_Comp = YES;
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
@@ -239,19 +252,6 @@ static void fanBoardPorcess(void)
     }
 }
 
-static void fanBoardSelfTest(void)
-{
-    if (ShmFanModuleData->SelfTest_Comp == YES) {
-        return;
-    }
-
-    GetFwAndHwVersion_Fan();
-    SetModelName_Fan();
-    SetRtcData_Fan();
-    sleep(1);
-    gettimeofday(&gFanBoardRunTimer, NULL);
-}
-
 void FanBoardTask(int uartFD)
 {
 #if defined NO_FAN_BOARD || defined DD360ComBox

+ 6 - 1
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/LEDlight.c

@@ -127,9 +127,10 @@ static void SetLedColor(void)
                 led_color.Connect_2_Red = _colorBuf;
             }
         } else {
+
+            // 實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -158,6 +159,8 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+
             }
 
             // --------------------------------------------------------------------------
@@ -191,6 +194,8 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+
             }
 
         }

+ 56 - 14
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c

@@ -25,7 +25,7 @@ static DcCommonInfo *ShmDcCommonData = NULL;
 static struct WARNING_CODE_INFO *pSysWarning = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
-
+static struct GBTData* ShmGBTData = NULL;
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
@@ -36,7 +36,8 @@ static uint16_t fanSpeedSmoothValue = 1000;
 static Led_Color cur_led_color = {COLOR_MIN_LV};
 static Led_Color led_color;
 static struct timeval _led_priority_time;
-
+int ReservationLed;
+time_t ReservationFlashTimer;
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
@@ -361,10 +362,17 @@ static void GetGfdAdc(void)
 void CheckOutputPowerOverCarReq(uint8_t index)
 {
     struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
-
+    ShmGBTData = (struct GBTData*)GetShmGBTData();
     float fireV = pDcChargingInfo->FireChargingVoltage;
     float carV = pDcChargingInfo->EvBatteryMaxVoltage * 10;
-
+    /*
+    log_info("PresentChargingVoltage:%f, FireChargingVoltage:%f ", pDcChargingInfo->PresentChargingVoltage * 10, pDcChargingInfo->FireChargingVoltage);
+    log_info("fireV:%f, carV:%f, _isOvpChkTimeFlag:%d", fireV, carV, _isOvpChkTimeFlag[index]);
+    log_info("EvBatterytargetVoltage:%f", pDcChargingInfo->EvBatterytargetVoltage);
+    if (pDcChargingInfo->Type == _Type_GB) {
+        log_info("GB EV Board Status:%d", ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
+    }
+    */
     if ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 1500 &&
             (pDcChargingInfo->Type == _Type_Chademo ||
              pDcChargingInfo->Type == _Type_CCS_2 ||
@@ -1398,16 +1406,16 @@ static void fanBoardPorcess(void)
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
             //GetPsuTempForFanSpeed();
-            GetFanSpeedByFunction();
+            //GetFanSpeedByFunction();
             GetFanSpeed();
             pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
             gettimeofday(&gFanBoardRunTimer, NULL);
-
+            /*
             ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-
+            */
             //log_info("set fan = %d ", ShmFanModuleData->SetFan1Speed);
             SetFanModuleSpeed();
         }
@@ -1488,11 +1496,9 @@ static void SetLedColor(void)
     } else {
         if (pSysInfo->IsAlternatvieConf) {
             if ((chargingData_1->SystemStatus == S_BOOTING ||
-                    chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    chargingData_1->SystemStatus == S_IDLE ) &&
                     (chargingData_2->SystemStatus == S_BOOTING ||
-                     chargingData_2->SystemStatus == S_IDLE ||
-                     chargingData_2->SystemStatus == S_RESERVATION)) {
+                     chargingData_2->SystemStatus == S_IDLE)) {
 #if defined DD360Audi
                 led_color.Connect_1_Green = _colorBuf;
                 led_color.Connect_1_Blue = _colorBuf;
@@ -1528,12 +1534,25 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
-            }
+            } else if (chargingData_1->SystemStatus == S_RESERVATION ||
+                chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
 
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
         } else {
+            //實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -1562,13 +1581,20 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
             }
 
 
             // --------------------------------------------------------------------------
             if (chargingData_2->SystemStatus == S_BOOTING ||
                     chargingData_2->SystemStatus == S_IDLE ||
-                    chargingData_2->SystemStatus == S_RESERVATION ||
                     chargingData_2->SystemStatus == S_MAINTAIN) {
                 if (chargingData_2->IsAvailable == NO) {
                     led_color.Connect_2_Green = COLOR_MIN_LV;
@@ -1596,6 +1622,14 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
             }
 
         }
@@ -1663,6 +1697,14 @@ static void LEDBoardProcess(void)
         //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
         //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
         //}
+        if (time((time_t*)NULL) - ReservationFlashTimer >= 3) {
+            ReservationFlashTimer = time((time_t*)NULL);
+            if (ReservationLed)
+                ReservationLed = 0;
+            else
+                ReservationLed = 1;
+        }
+
         SetLedColor();
         gettimeofday(&_led_priority_time, NULL);
     }

+ 258 - 301
EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -31,229 +31,6 @@ static struct ChargingInfoData *pDcChargingInfo = NULL;
 static struct ChargingInfoData *pAcChargingInfo = NULL;
 static DcCommonInfo *ShmDcCommonData            = NULL;
 
-bool needReloadQr = true;
-bool _saftydetect = false;
-bool _isShow = false; //DS60-120 add
-uint8_t _showInformIndex = 0; //DS60-120 add
-
-int _port;
-//char* pPortName         = "/dev/ttyO2";
-char *pPortName           = "/dev/ttyS3";
-char *moduleName          = "DMT80480T070_09WT";
-uint8_t _totalCount;
-uint8_t acgunCount;
-//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
-
-uint8_t ac_ani_battery_level    = _BATTERY_LEVEL_FOR_MAP_LV5;
-uint8_t isDiffStatus            = false;
-uint8_t isChangeBattMap         = false;
-// 當前選擇的槍號
-#if defined DD360Audi
-short _currentPage              = _LCM_SELECT_GUN;
-short _oldPage                  = _LCM_SELECT_GUN;
-#else
-short _currentPage              = _LCM_NONE;
-short _oldPage                  = _LCM_NONE;
-#endif //defined DD360Audi
-uint8_t _gunIndex               = 0;
-bool _wifi_conn_status          = false;
-bool _battery_display_ani       = false;
-uint8_t _curPage_index          = 0;
-bool _page_reload               = false;
-
-// LCM - HW
-uint8_t _everyPageRollChange    = 0;
-short __logo                    = 0x0000;
-short __conn_status             = 0x0030;
-short __ethernet_status         = 0x0032;
-short __3G4G_status             = 0x0036;
-short __3G4G_status1            = 0x0037;
-short __3G4G_move_status        = 0x0038;
-short __wifi_status             = 0x003C;
-
-short __sel_gun_btn             = 0x0040;
-short __ret_home_btn            = 0x0042;
-short __stop_method_btn         = 0x0044;
-short __lcm_version             = 0x004A;
-short __qr_code                 = 0x0250;
-short __main_rfid               = 0x0052;
-short __main_qr                 = 0x0054;
-short __main_app                = 0x0056;
-
-short __plug_in_arrow           = 0x0060;
-
-short __conn_line               = 0x0066;
-
-short __gun_type_index          = 0x0070;
-short __cmp_gun_type_index      = 0x0080; ////For Audi
-short __batt_map_empty          = 0x0090; ////For Audi
-short __qr_code_pre             = 0x0280;
-
-short __side_top                = 0x0090;
-short __side_down               = 0x0092;
-short __side_mid                = 0x0094;
-
-short __conn_line_chag          = 0x0096;
-short __batt_map                = 0x0100;
-short __soc_value_charging      = 0x0102;
-short __remain_time_map         = 0x0106;
-short __power_map               = 0x0108;
-short __energy_map              = 0x010A;
-short __remain_time_tx          = 0x0110;
-
-short __trp_remain_time_map     = 0x0116;
-short __trp_power_map           = 0x0118;
-short __trp_energy_map          = 0x011A;
-
-short __output_eng_tx           = 0x0120;
-short __total_out_eng_tx        = 0x0130;
-short __conn_line_comp          = 0x0140;
-short __charging_fee_map        = 0x0146;
-short __charging_fee_tx         = 0x0150;
-
-short __money_by_rate           = 0x0200;
-short __money_rate              = 0x0220;
-short __money_rate_map          = 0x0230;
-
-//DS60-120 add
-short __csu_ver_string          = 0x0300;
-short __csu_ver_value           = 0x0310;
-short __fan_speed_string        = 0x0390;
-short __fan_speed_value         = 0x0400;
-
-short __dc1_ver_string          = 0x0320;
-short __dc1_ver_value           = 0x0330;
-short __dc2_ver_string          = 0x0340;
-short __dc2_ver_value           = 0x0350;
-short __eth0_ip_string          = 0x0360;
-short __eth0_ip_value           = 0x0370;
-short __sn_string               = 0x0410;
-short __sn_value                = 0x0420;
-
-//For Audi, for select gun
-short __left_gun_map            = 0x0260;
-short __right_gun_map           = 0x0262;
-short __add_chk_btn             = 0x0264;
-//short __station_id            = 0x0270;
-short __balance                 = 0x0270;
-short __remain_balance          = 0x0280;
-short __custStationIdL1         = 0x0450;
-//short __custStationIdL2       = 0x0470;
-short _emergency_map            = 0x011C;
-short __logo_cmp                = 0x014A;
-// ICON ID
-uint8_t _disappear              = 0;
-uint8_t _disconnect             = 1;
-uint8_t _connect                = 2;
-uint8_t _warning                = 3;
-uint8_t _arrow_dark             = 4;
-uint8_t _arrow_light            = 5;
-uint8_t _3G4G_disconnect        = 6;
-uint8_t __3G4G_connect          = 7;
-uint8_t _wifi_disconnect        = 8;
-uint8_t _wifi_connect           = 9;
-uint8_t _logo                   = 10;
-uint8_t _conn_map1              = 11;
-uint8_t _conn_map2              = 12;
-uint8_t _sel_gun_btn            = 13;
-uint8_t _back_home_btn          = 14;
-uint8_t _stop_charging_btn      = 15;
-uint8_t _stop_charging_btn_scan = 16;
-uint8_t _chademo_dark           = 17;
-uint8_t _ccs_dark               = 18;
-uint8_t _gbt_dark               = 19;
-uint8_t _actype_dark            = 20;
-uint8_t _chademo_light          = 21;
-uint8_t _ccs_light              = 22;
-uint8_t _gbt_light              = 23;
-uint8_t _actype_light           = 24;
-uint8_t _main_none_rfid         = 25;
-uint8_t _main_rfid              = 26;
-uint8_t _main_none_app          = 27;
-uint8_t _main_app               = 28;
-uint8_t _main_none_qr           = 29;
-uint8_t _main_qr                = 30;
-uint8_t _charging_map1          = 31;
-uint8_t _charging_map2          = 32;
-uint8_t _battery_empty          = 33;
-uint8_t _battery_cap_20         = 34;
-uint8_t _battery_cap_40         = 35;
-uint8_t _battery_cap_60         = 36;
-uint8_t _battery_cap_80         = 37;
-uint8_t _battery_cap_100        = 38;
-uint8_t _battery_map            = 39;
-uint8_t _power_map              = 40;
-uint8_t _time_map               = 41;
-uint8_t _complete_map           = 42;
-uint8_t _battery_soc_20         = 43;
-uint8_t _battery_soc_40         = 44;
-uint8_t _battery_soc_60         = 45;
-uint8_t _battery_soc_80         = 46;
-uint8_t _battery_soc_100        = 47;
-uint8_t _battery_eng_map        = 48;
-uint8_t _money_map              = 49;
-uint8_t _elapse_time_map        = 50;
-uint8_t _charging_money         = 51;
-//uint8_t _side_none_rfid       = 52;
-//uint8_t _side_rfid            = 53;
-//uint8_t _side_none_app        = 54;
-//uint8_t _side_app             = 55;
-//uint8_t _side_none_qr         = 56;
-//uint8_t _side_qr              = 57;
-uint8_t _eth_disconnect         = 52; //58;
-uint8_t _eth_connect            = 53; //59;
-
-uint8_t _chademo_dark_cmp       = 54;
-uint8_t _ccs_dark_cmp           = 55;
-uint8_t _gbt_dark_cmp           = 56;
-uint8_t _actype_dark_cmp        = 57;
-uint8_t _chademo_light_cmp      = 58;
-uint8_t _ccs_light_cmp          = 59;
-uint8_t _gbt_light_cmp          = 60;
-uint8_t _actype_light_cmp       = 61;
-
-uint8_t _logo_cmp               = 62;
-uint8_t _battery_eng_trp_map    = 63;
-uint8_t _money_trp_map          = 64;
-uint8_t _elapse_time_trp_map    = 65;
-#if defined DD360Audi
-////For Audi
-uint8_t _left_gun_disable_map   = 66;
-uint8_t _left_gun_enable_map    = 67;
-uint8_t _right_gun_disable_map  = 68;
-uint8_t _right_gun_enable_map   = 69;
-uint8_t _select_gun_btn         = 70;
-uint8_t _emergency_disable_map  = 72;
-// For replug
-struct timespec showReplugStrTimer;
-struct timespec showFullTargetTimer;
-short __show_StatusString_value_1 = 0x0460;
-short __show_StatusString_value_2 = 0x0462;
-uint8_t _showfulltarget_1       = 73;
-uint8_t _showfulltarget_2       = 74;
-uint8_t _showReplugStr_1        = 75;
-uint8_t _showReplugStr_2        = 76;
-// Select Gun for Audi
-short __show_selectgun_value    = 0x0464;
-uint8_t _showselectgun_left     = 77;
-uint8_t _showselectgun_right    = 78;
-// Wait for gun plugin Audi
-short __show_waitgunplug_value    = 0x0468;
-uint8_t _showwaitgunplug_left     = 80;
-uint8_t _showwaitgunplug_right    = 81;
-#else
-short __show_handshark_value    = 0x0464;
-short __show_GFD_value          = 0x0466;
-short __show_precharge_value    = 0x0468;
-
-uint8_t _show_handshark_dark    = 67;
-uint8_t _show_handshark_light   = 68;
-uint8_t _show_GFD_dark          = 69;
-uint8_t _show_GFD_light         = 70;
-uint8_t _show_precharge_dark    = 71;
-uint8_t _show_precharge_light   = 72;
-#endif
 //#define log_info(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_error(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -432,8 +209,8 @@ void ReadMsgFromLcm(uint8_t *msg, uint8_t readLen)
             {
                 if(strcmp((char *)pSysInfo->LcmHwRev, "") != EQUAL)
                     strcpy((char *)pSysInfo->LcmHwRev, moduleName);
-
-                ShmDcCommonData->LcmFwVersion = atoi((char *)(msg + 7));
+                if (atoi((char*)(msg + 7)) != 0)
+                    ShmDcCommonData->LcmFwVersion = atoi((char*)(msg + 7));
                 //printf("msg = %d \n", ShmDcCommonData->LcmFwVersion);
     //              printf("msg = %x \n", *(msg + 7));
     //              printf("msg = %x \n", *(msg + 8));
@@ -521,7 +298,25 @@ void DisplayValueToLcm(short address, uint8_t *data, uint8_t len)
 
     WriteCmdToLcm(cmd, cmd[2] + 3);
 }
+void DisplayFeeValueToLcm(short address, uint8_t* data, uint8_t len)
+{
+    uint8_t cmd[256];
+    memset(cmd, 0x00, sizeof(cmd));
 
+    cmd[0] = CMD_TITLE_1;
+    cmd[1] = CMD_TITLE_2;
+    cmd[2] = 0x03 + len;
+    cmd[3] = CMD_MULTI_WRITE;
+    cmd[4] = address >> 8;
+    cmd[5] = address & 0x00FF;
+
+    for (uint8_t count = 0; count < len; count++)
+    {
+        cmd[12 + count] = *(data + count);
+    }
+
+    WriteCmdToLcm(cmd, cmd[2] + 3);
+}
 void ChangeDisplay2Value(short address, short value)
 {
     uint8_t data[2];
@@ -579,7 +374,7 @@ void ChangeWarningFunc()
     //log_info("WarningCount = %d ", pSysWarning->WarningCount);
 //#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
     for (i = 0; (i + pSysWarning->PageIndex * 5) < pSysWarning->WarningCount; i++) {
-        log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
+        //log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
         memset(cmd, 0x00, sizeof(cmd));
         if ((i) >= 5) {
             break;
@@ -840,6 +635,7 @@ uint8_t demoCount = 0;
 void DemoFunction()
 {
     if (demoCount == 0) {
+        /*
         pSysWarning->WarningCount = 6;
         memcpy(&pSysWarning->WarningCode[0][0], "000001", 7);
         memcpy(&pSysWarning->WarningCode[1][0], "000002", 7);
@@ -847,24 +643,38 @@ void DemoFunction()
         memcpy(&pSysWarning->WarningCode[3][0], "000004", 7);
         memcpy(&pSysWarning->WarningCode[4][0], "000005", 7);
         memcpy(&pSysWarning->WarningCode[5][0], "000006", 7);
+        */
     } else {
         if (demoCount == 20) {
             pSysInfo->PageIndex = _LCM_IDLE;
-        } else if (demoCount == 80) {
+            /*
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_AUTHORIZING;
-        } else if (demoCount == 100) {
+        } else if (demoCount == 80) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_COMP;
-        } else if (demoCount == 120) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_FAIL;
-        } else if (demoCount == 140) {
+            */
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_PRE_CHARGE;
-        } else if (demoCount == 180) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_CHARGING;
+        } else if (demoCount == 160) {
+            pSysInfo->PageIndex = _LCM_COMPLETE;
         }
     }
+    pSysInfo->CurGunSelected = LEFT_GUN_NUM;
+    sprintf((char*)ShmDcCommonData->QRCodeString, "%s", pSysConfig->SystemId);
 
-    if (demoCount < 180) {
+    sprintf((char*)ShmDcCommonData->pGunInfo[LEFT_GUN_NUM].ReceiptInfo, "%s", pSysConfig->SystemId);
+    pSysConfig->BillingData.isBilling = 1;
+    sprintf((char*)ShmDcCommonData->DefaultPriceString, "AM10:~10:00:$ 2, AM10:00~PM05:00:$ 3, PM05:00~AM00:00:$ 2");
+
+
+    if (demoCount <= 200) {
         demoCount++;
+    } else {
+        demoCount = 0;
     }
 }
 
@@ -1117,6 +927,7 @@ void ChangeRemainTime(int sec)
     s = (sec - (3600 * h) - (m * 60));
     sprintf((char *)value, "%02d:%02d:%02d", h, m, s);
     string2ByteArray(value, cmd);
+
     DisplayValueToLcm(__remain_time_tx, cmd, sizeof(cmd));
 }
 
@@ -1126,12 +937,10 @@ void ChangeChargingEnergyValue(float energy)
     uint8_t value[10];
 
     memset(cmd, 0x00, sizeof(cmd));
-    if (energy >= 0.05) {
-        energy -= 0.05;
-    }
-    sprintf((char *) value, "%.1f kWh", energy);
+
+    sprintf((char*)value, "%.4f kWh", energy);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__total_out_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_energy, cmd, sizeof(cmd));
 }
 
 void ChangeChargingPowerValue(float pow)
@@ -1146,7 +955,7 @@ void ChangeChargingPowerValue(float pow)
 //  pow = (max - min) * rand() / (RAND_MAX + 1.0) + min;
     sprintf((char *) value, "%.1f kW", pow);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__output_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_power, cmd, sizeof(cmd));
 }
 
 void ChangeChargingFeeValue(float fee)
@@ -1161,6 +970,62 @@ void ChangeChargingFeeValue(float fee)
     DisplayValueToLcm(__charging_fee_tx, cmd, sizeof(cmd));
 }
 
+void ChangeEnergyCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+    if (fee >= 0 )
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_EnergyCost, cmd, sizeof(cmd));
+}
+void ChangeParkingFeeValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_ParkingFee, cmd, sizeof(cmd));
+}
+void ChangeTotalCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_TotalCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_TotalCost, cmd, sizeof(cmd));
+}
 void DisplayMoneyRate(float money)
 {
     uint8_t cmd[8];
@@ -1186,6 +1051,13 @@ void DisplayMoneyCur(uint8_t *cur)
     string2ByteArray(buf, cmd);
     DisplayValueToLcm(__money_rate, cmd, sizeof(cmd));
 }
+void DisplayReceipt(char* pString)
+{
+    char data[200];
+    memset(data, '\0', sizeof(data));
+    strcpy(data, pString);
+    DisplayValueToLcm(__Receipt_value, data, 200);
+}
 
 void RefreshPageAnimation(uint8_t value)
 {
@@ -1579,6 +1451,29 @@ void DisplayInfoEthIp(bool isShow, uint8_t *ip)
     }
 }
 
+void DisplayInfoConsumption(bool isShow)
+{
+    float data = 0;
+    if (isShow) {
+        uint8_t value[20];
+
+        memset(value, 0x00, sizeof(value));
+        strcpy((char*)value, "PWCT >");
+        DisplayValueToLcm(__eth0_ip_string, value, sizeof(value));
+        memset(value, 0x00, sizeof(value));
+        data = ShmDcCommonData->pConsumption.Gun1_Consumption +
+            ShmDcCommonData->pConsumption.Gun2_Consumption +
+            ShmDcCommonData->pConsumption.Gun3_Consumption +
+            ShmDcCommonData->pConsumption.Gun4_Consumption;
+
+        sprintf((char*)value,"%.4f",data);
+
+        DisplayValueToLcm(__eth0_ip_value, value, sizeof(value));
+    } else {
+        ChangeDisplay2Value(__eth0_ip_string, _disappear);
+        ChangeDisplay2Value(__eth0_ip_value, _disappear);
+    }
+}
 void Show4GRssi(bool isShow, int dbValue)
 {
     if (isShow) {
@@ -1745,8 +1640,7 @@ void InformationShow()
             DisplayInfoCsuVer(show, pSysInfo->CsuRootFsFwRev);
             DisplayInfoSpeed(show, pSysInfo->SystemFanRotaSpeed);
             DisplayInfoSN(show, pSysConfig->SerialNumber);
-
-            DisplayInfoEthIp(show, pSysConfig->Eth0Interface.EthIpAddress);
+            DisplayInfoConsumption(show);
             DisplayInfoGun1Ver(show, pSysInfo->Connector1FwRev);
             if (_totalCount > 1) {
                 DisplayInfoGun2Ver(show, pSysInfo->Connector2FwRev);
@@ -1808,14 +1702,58 @@ void ChangeTimeValue(uint8_t time)
     string2ByteArray(value, cmd);
     DisplayValueToLcm(0x1290, cmd, sizeof(cmd));
 }
+void ShowDateTime()
+{
+    struct timeb SeqEndTime;
+    struct tm* tm;
+    char _date[20];
+    char _time[20];
+    char _am_pm[10];
+
+    ftime(&SeqEndTime);
+    SeqEndTime.time = time(NULL);
+    
+    tm = localtime(&SeqEndTime.time);
+
+    sprintf(_date, "%04d/%02d/%02d",
+        tm->tm_year + 1900,
+        tm->tm_mon + 1,
+        tm->tm_mday);
 
+    if (tm->tm_hour >= 12) {
+        sprintf(_am_pm,"p.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour-12,
+            tm->tm_min);
+    } else {
+        sprintf(_am_pm, "a.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour,
+            tm->tm_min);
+    }
+    DisplayValueToLcm(__date_map, _date, strlen(_date)+1);
+    DisplayValueToLcm(__time_map, _time, strlen(_time)+1);
+    DisplayValueToLcm(__time_am_pm, _am_pm, strlen(_am_pm)+1);
+}
+uint8_t old_string[255];
+void ShowAnimationPrice(char* pString)
+{
+    uint8_t cmd[230];
+    memset(cmd, 0x00, sizeof(cmd));
+    string2ByteArray((uint8_t*)pString,cmd);
+    int len = strlen(pString);
+
+    if (strcmp((char*)old_string, pString) != EQUAL) {
+        strcpy((char*)old_string, pString);
+        DisplayFeeValueToLcm(__Animation_Price, cmd, sizeof(cmd));
+    }
+}
 void ProcessPageInfo()
 {
     _page_reload = IsPageReloadChk();
     pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
     struct InfoCodeData *pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData();
     struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
-    uint8_t i;
 
     // 隨插即充 - 可省略該按鈕 //DS60-120 add
     if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) {
@@ -1827,6 +1765,9 @@ void ProcessPageInfo()
         }
     }
     showPhihongLogo(false);
+    // Show Time
+    ShowDateTime();
+
     switch (_currentPage) {
 #if defined DD360Audi
     case _LCM_SELECT_GUN: ////For Audi
@@ -1842,7 +1783,7 @@ void ProcessPageInfo()
 #endif //defined DD360Audi
 
     case _LCM_IDLE: {
-
+        ChangeDisplayMoneyInfo();
         if (pSysConfig->isRFID) {
             ChangeDisplay2Value(__main_rfid, _main_rfid);
         } else {
@@ -1871,6 +1812,8 @@ void ProcessPageInfo()
         //if (FirstPageChanged() == YES || needReloadQr || _page_reload) {
         if (pSysConfig->isQRCode) {
             needReloadQr = false;
+            ChangeQrCode_Idle((char*)ShmDcCommonData->QRCodeString);
+            /*
             if (pSysConfig->QRCodeMadeMode == NO) {
                 //uint8_t len = strlen((char *)pSysConfig->SystemId);
                 ChangeQrCode_Idle((char *)pSysConfig->SystemId);
@@ -1879,6 +1822,7 @@ void ProcessPageInfo()
                 ChangeQrCode_Idle((char *)pSysConfig->QRCodeContent);
             }
             //ChangeQrCode_Idle((char *)pSysConfig->SystemId);
+            */
         }
         //}
 
@@ -1979,7 +1923,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2008,7 +1952,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
 
@@ -2047,6 +1991,8 @@ void ProcessPageInfo()
             }
         }
 
+        ChangeDisplay2Value(__money_by_rate, _disappear);
+
         gunTargetIndex = 0; //DS60-120 add
         for (uint8_t i = 0; i < _totalCount; i++) {
             if (_totalCount == 1 && acgunCount <= 0) { //DS60-120 add
@@ -2111,53 +2057,16 @@ void ProcessPageInfo()
             if (_currentPage == _LCM_PRE_CHARGE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
                     ChangeBattMapAndValue(_currentPage, pDcChargingInfo->EvBatterySoc);
-                    uint8_t precharg_time = (GetPreChargeTimeoutValue(pDcChargingInfo->PreChargeTimer)/1) / uSEC_VAL;
-                    if (precharg_time > PRECHARGING_TTIMEOUT)
-                        precharg_time = PRECHARGING_TTIMEOUT;
-                    ChangeTimeValue(PRECHARGING_TTIMEOUT- precharg_time);
-
-                    if (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                            pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EV) {
-                        pDcChargingInfo->_SaftyDetect = false;
-                        ChangeDisplay2Value(__show_handshark_value, _show_handshark_light);
-                        ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                        ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-
-                    } else if (pDcChargingInfo->SystemStatus == S_PREPARING_FOR_EVSE) {
-                        if (pDcChargingInfo->Type == _Type_Chademo || pDcChargingInfo->Type == _Type_GB) {
-                            if (pDcChargingInfo->_SaftyDetect == false ) {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                                if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                    pDcChargingInfo->_SaftyDetect = true;
-                            } else {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                            }
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                        }
-                    } else if (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0 ||
-                            pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1) {
-                        if (pDcChargingInfo->_SaftyDetect == false ) {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                            if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                pDcChargingInfo->_SaftyDetect = true;
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                        }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
                     } else {
-                        ChangeDisplay2Value(__show_handshark_value, _disappear);
-                        ChangeDisplay2Value(__show_GFD_value, _disappear);
-                        ChangeDisplay2Value(__show_precharge_value, _disappear);
+                        ShowAnimationPrice("");
                     }
                 }
             } else if (_currentPage == _LCM_CHARGING && !isShowAc) {
@@ -2177,7 +2086,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2190,6 +2099,21 @@ void ProcessPageInfo()
                     } else {
                         ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                        ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee > 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
+                    } else {
+                        ShowAnimationPrice("");
+                    }
                 }
             } else if (_currentPage == _LCM_COMPLETE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
@@ -2207,8 +2131,9 @@ void ProcessPageInfo()
                     } else {
                         ChangeChargingPowerValue(0);
                     }
+
 #if 1
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2224,6 +2149,23 @@ void ProcessPageInfo()
                             ChangeBalanceValue(__remain_balance, i);
                         }
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    if (strlen((char*)ShmDcCommonData->pGunInfo[i].ReceiptInfo) > 0) {
+                        DisplayReceipt(ShmDcCommonData->pGunInfo[i].ReceiptInfo);
+                        ChangeDisplay2Value(__receipt_backgroud, _receipt_bk);
+                    } else {
+                        DisplayReceipt("");
+                        ChangeDisplay2Value(__receipt_backgroud, _disappear);
+                    }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee >= 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+                    
 #else
                     ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2274,6 +2216,8 @@ void ProcessPageInfo()
                     if (pSysConfig->isQRCode) {
                         needReloadQr = false;
                         //ChangeQrCode_Charge((char *)pSysConfig->SystemId); //DS60-120 remove
+                        ChangeQrCode_Charge((char*)ShmDcCommonData->QRCodeString);
+                        /*
                         if (pSysConfig->QRCodeMadeMode == NO) {
                             //uint8_t len = strlen((char *)pSysConfig->SystemId);
                             ChangeQrCode_Charge((char *)pSysConfig->SystemId);
@@ -2281,6 +2225,7 @@ void ProcessPageInfo()
                             //uint8_t len = strlen((char *)pSysConfig->QRCodeContent);
                             ChangeQrCode_Charge((char *)pSysConfig->QRCodeContent);
                         }
+                        */
                     }
                 }
             }
@@ -2302,6 +2247,11 @@ void ProcessPageInfo()
             break;
             }
         }
+#else
+        if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == 1) {
+            ChangeToOtherPage(_LCM_EMERGENCY);
+            break;
+        }
 #endif
 
         break;
@@ -2325,10 +2275,11 @@ void ChangeDisplayMoneyInfo()
             DisplayMoneyRate(ShmSelectGunInfo->PricesInfo[curGun].UserPrices);
         } else {
 #endif //defined DD360Audi
-            if (tmCSU->tm_hour <= 23) {
-                pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
-                DisplayMoneyRate(pSysConfig->BillingData.Cur_fee);
-            }
+
+            pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
+            ChangeDisplay2Value(__money_by_rate, _disappear);
+            ShowAnimationPrice(ShmDcCommonData->DefaultPriceString);
+
 
             if (pSysConfig->BillingData.Currency <= 53) {
                 DisplayMoneyCur((uint8_t *)GetCurrency(pSysConfig->BillingData.Currency));
@@ -2340,6 +2291,7 @@ void ChangeDisplayMoneyInfo()
         ChangeDisplay2Value(__money_rate_map, _disappear);
         ChangeDisplay2Value(__money_by_rate, _disappear);
         ChangeDisplay2Value(__money_rate, _disappear);
+        ShowAnimationPrice("");
     }
 }
 
@@ -2390,6 +2342,7 @@ void DefaultIconStatus()
     for (uint8_t i = 0; i < 3; i++) {
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
+    ChangeDisplay2Value(__sel_gun_btn, _disappear);
 
     if (pSysInfo->IsAlternatvieConf == YES || _totalCount == 1) {
         ChangeDisplay2Value(__sel_gun_btn, _disappear);
@@ -2429,7 +2382,7 @@ int main(void)
     pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
-    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();;
+    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
     ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
     struct StatusCodeData *ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();;
@@ -2438,6 +2391,7 @@ int main(void)
     _port = CreateCommunicationLcmPort();
     uint8_t changeWarningPriority = 0;
     uint8_t curWarningCount = 255;
+    uint8_t changeInfoPriority = 0;
     ChangeBackLight(true);
     _totalCount = pSysConfig->TotalConnectorCount;
     acgunCount = pSysConfig->AcConnectorCount;
@@ -2450,7 +2404,7 @@ int main(void)
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
 
-    uint8_t _verShowCount = 3;
+    uint8_t _verShowCount = 5;
     DefaultIconStatus(); //DS60-120 add
 
     while (_port != -1) {
@@ -2501,10 +2455,13 @@ int main(void)
 #if defined DD360Audi
             ChangeDisplayMoneyInfo();
 #else
-            if (changeWarningPriority == 0) { ////For Audi
-                ChangeDisplayMoneyInfo();
-                InformationShow();
+            InformationShow();
+            /*
+            if (changeInfoPriority == 0) { ////For Audi
+                //ChangeDisplayMoneyInfo();
+                
             }
+            */
 #endif //defined DD360Audi
 
             changeWarningPriority >= 15 ? (_battery_display_ani = true) : (_battery_display_ani = false);

+ 278 - 4
EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.h

@@ -1,6 +1,35 @@
 #ifndef MODULE_LCM_CTRL_H_
 #define MODULE_LCM_CTRL_H_
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
 
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+#include    "../Define/define.h"
+#include    "../Config.h"
 //------------------------------------------------------------------------------
 #define DEFAULT_AC_INDEX                        (2)
 
@@ -17,10 +46,6 @@
 
 #define CMD_BACKLIGHT                           (0x01)
 #define CMD_REGISTER                            (0x03)
-
-//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
-#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
-
 //------------------------------------------------------------------------------
 enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_EMP = 0x00,
@@ -31,4 +56,253 @@ enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_LV5 = 0x05,
 };
 
+
+//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
+#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
+#define CTEP_VERSION 002
+bool needReloadQr = true;
+bool _saftydetect = false;
+bool _isShow = false; //DS60-120 add
+uint8_t _showInformIndex = 0; //DS60-120 add
+
+int _port;
+//char* pPortName         = "/dev/ttyO2";
+char* pPortName = "/dev/ttyS3";
+char* moduleName = "DMT80480T070_09WT";
+uint8_t _totalCount;
+uint8_t acgunCount;
+//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
+
+uint8_t ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV5;
+uint8_t isDiffStatus = false;
+uint8_t isChangeBattMap = false;
+// 當前選擇的槍號
+#if defined DD360Audi
+short _currentPage = _LCM_SELECT_GUN;
+short _oldPage = _LCM_SELECT_GUN;
+#else
+short _currentPage = _LCM_NONE;
+short _oldPage = _LCM_NONE;
+#endif //defined DD360Audi
+uint8_t _gunIndex = 0;
+bool _wifi_conn_status = false;
+bool _battery_display_ani = false;
+uint8_t _curPage_index = 0;
+bool _page_reload = false;
+
+// LCM - HW
+uint8_t _everyPageRollChange = 0;
+short __logo = 0x0000;
+short __conn_status = 0x0030;
+short __ethernet_status = 0x0032;
+short __3G4G_status = 0x0036;
+short __3G4G_status1 = 0x0037;
+short __3G4G_move_status = 0x0038;
+short __wifi_status = 0x003C;
+
+short __sel_gun_btn = 0x0040;
+short __ret_home_btn = 0x0042;
+short __stop_method_btn = 0x0044;
+short __lcm_version = 0x004A;
+short __qr_code = 0x0250;
+short __main_rfid = 0x0052;
+short __main_qr = 0x0054;
+short __main_app = 0x0056;
+
+short __plug_in_arrow = 0x0060;
+
+short __conn_line = 0x0066;
+
+short __gun_type_index = 0x0070;
+short __cmp_gun_type_index = 0x0080; ////For Audi
+short __batt_map_empty = 0x0090; ////For Audi
+short __qr_code_pre = 0x0280;
+
+short __side_top = 0x0090;
+short __side_down = 0x0092;
+short __side_mid = 0x0094;
+
+short __conn_line_chag = 0x0096;
+short __batt_map = 0x0100;
+short __soc_value_charging = 0x0102;
+short __remain_time_map = 0x0106;
+short __power_map = 0x0108;
+short __energy_map = 0x010A;
+short __remain_time_tx = 0x0110;
+
+short __trp_remain_time_map = 0x0116;
+short __trp_power_map = 0x0118;
+short __trp_energy_map = 0x011A;
+
+short __output_eng_tx = 0x0120;
+short __total_out_eng_tx = 0x0130;
+short __conn_line_comp = 0x0140;
+short __charging_fee_map = 0x0146;
+short __charging_fee_tx = 0x0150;
+
+short __money_by_rate = 0x0200;
+short __money_rate = 0x0220;
+short __money_rate_map = 0x0230;
+
+//DS60-120 add
+short __csu_ver_string = 0x0300;
+short __csu_ver_value = 0x0310;
+short __fan_speed_string = 0x0390;
+short __fan_speed_value = 0x0400;
+
+short __dc1_ver_string = 0x0320;
+short __dc1_ver_value = 0x0330;
+short __dc2_ver_string = 0x0340;
+short __dc2_ver_value = 0x0350;
+short __eth0_ip_string = 0x0360;
+short __eth0_ip_value = 0x0370;
+short __sn_string = 0x0410;
+short __sn_value = 0x0420;
+
+//For Audi, for select gun
+short __left_gun_map = 0x0260;
+short __right_gun_map = 0x0262;
+short __add_chk_btn = 0x0264;
+//short __station_id            = 0x0270;
+short __balance = 0x0270;
+short __remain_balance = 0x0280;
+short __custStationIdL1 = 0x0450;
+//short __custStationIdL2       = 0x0470;
+short _emergency_map = 0x011C;
+short __logo_cmp = 0x014A;
+
+// CTEP
+short __remain_time = 0x0110;
+short __present_power = 0x0120;
+short __present_energy = 0x0130;
+short __date_map = 0x0470;
+short __time_map = 0x0480;
+short __time_am_pm = 0x0489;
+short __Prepare_EnergyCost = 0x0500;
+short __Prepare_ParkingFee = 0x0510;
+short __Charge_EnergyCost = 0x0610;
+short __Charge_ParkingFee = 0x0620;
+short __Charge_TotalCost = 0x0630;
+short __Complete_EnergyCost = 0x0640;
+short __Complete_ParkingFee = 0x0650;
+short __Complete_TotalCost = 0x0660;
+short __Receipt_value = 0x0670;
+short __Animation_Price = 0x6010;
+short __receipt_backgroud = 0x0700;
+// ICON ID
+uint8_t _disappear = 0;
+uint8_t _disconnect = 1;
+uint8_t _connect = 2;
+uint8_t _warning = 3;
+uint8_t _arrow_dark = 4;
+uint8_t _arrow_light = 5;
+uint8_t _3G4G_disconnect = 6;
+uint8_t __3G4G_connect = 7;
+uint8_t _wifi_disconnect = 8;
+uint8_t _wifi_connect = 9;
+uint8_t _logo = 10;
+uint8_t _conn_map1 = 11;
+uint8_t _conn_map2 = 12;
+uint8_t _sel_gun_btn = 13;
+uint8_t _back_home_btn = 14;
+uint8_t _stop_charging_btn = 15;
+uint8_t _stop_charging_btn_scan = 16;
+uint8_t _chademo_dark = 17;
+uint8_t _ccs_dark = 18;
+uint8_t _gbt_dark = 19;
+uint8_t _actype_dark = 20;
+uint8_t _chademo_light = 21;
+uint8_t _ccs_light = 22;
+uint8_t _gbt_light = 23;
+uint8_t _actype_light = 24;
+uint8_t _main_none_rfid = 25;
+uint8_t _main_rfid = 26;
+uint8_t _main_none_app = 27;
+uint8_t _main_app = 28;
+uint8_t _main_none_qr = 29;
+uint8_t _main_qr = 30;
+uint8_t _charging_map1 = 31;
+uint8_t _charging_map2 = 32;
+uint8_t _battery_empty = 33;
+uint8_t _battery_cap_20 = 34;
+uint8_t _battery_cap_40 = 35;
+uint8_t _battery_cap_60 = 36;
+uint8_t _battery_cap_80 = 37;
+uint8_t _battery_cap_100 = 38;
+uint8_t _battery_map = 39;
+uint8_t _power_map = 40;
+uint8_t _time_map = 41;
+uint8_t _complete_map = 42;
+uint8_t _battery_soc_20 = 43;
+uint8_t _battery_soc_40 = 44;
+uint8_t _battery_soc_60 = 45;
+uint8_t _battery_soc_80 = 46;
+uint8_t _battery_soc_100 = 47;
+uint8_t _battery_eng_map = 48;
+uint8_t _money_map = 49;
+uint8_t _elapse_time_map = 50;
+uint8_t _charging_money = 51;
+//uint8_t _side_none_rfid       = 52;
+//uint8_t _side_rfid            = 53;
+//uint8_t _side_none_app        = 54;
+//uint8_t _side_app             = 55;
+//uint8_t _side_none_qr         = 56;
+//uint8_t _side_qr              = 57;
+uint8_t _eth_disconnect = 52; //58;
+uint8_t _eth_connect = 53; //59;
+
+uint8_t _chademo_dark_cmp = 54;
+uint8_t _ccs_dark_cmp = 55;
+uint8_t _gbt_dark_cmp = 56;
+uint8_t _actype_dark_cmp = 57;
+uint8_t _chademo_light_cmp = 58;
+uint8_t _ccs_light_cmp = 59;
+uint8_t _gbt_light_cmp = 60;
+uint8_t _actype_light_cmp = 61;
+
+uint8_t _logo_cmp = 62;
+uint8_t _battery_eng_trp_map = 63;
+uint8_t _money_trp_map = 64;
+uint8_t _elapse_time_trp_map = 65;
+#if defined DD360Audi
+////For Audi
+uint8_t _left_gun_disable_map = 66;
+uint8_t _left_gun_enable_map = 67;
+uint8_t _right_gun_disable_map = 68;
+uint8_t _right_gun_enable_map = 69;
+uint8_t _select_gun_btn = 70;
+uint8_t _emergency_disable_map = 72;
+// For replug
+struct timespec showReplugStrTimer;
+struct timespec showFullTargetTimer;
+short __show_StatusString_value_1 = 0x0460;
+short __show_StatusString_value_2 = 0x0462;
+uint8_t _showfulltarget_1 = 73;
+uint8_t _showfulltarget_2 = 74;
+uint8_t _showReplugStr_1 = 75;
+uint8_t _showReplugStr_2 = 76;
+// Select Gun for Audi
+short __show_selectgun_value = 0x0464;
+uint8_t _showselectgun_left = 77;
+uint8_t _showselectgun_right = 78;
+// Wait for gun plugin Audi
+short __show_waitgunplug_value = 0x0468;
+uint8_t _showwaitgunplug_left = 80;
+uint8_t _showwaitgunplug_right = 81;
+#else
+short __show_handshark_value = 0x0464;
+short __show_GFD_value = 0x0466;
+short __show_precharge_value = 0x0468;
+uint8_t _receipt_bk = 67;
+
+uint8_t _show_handshark_dark = 67;
+uint8_t _show_handshark_light = 68;
+uint8_t _show_GFD_dark = 69;
+uint8_t _show_GFD_light = 70;
+uint8_t _show_precharge_dark = 71;
+uint8_t _show_precharge_light = 72;
+#endif
+
+
 #endif //MODULE_LCM_CTRL_H_

+ 11 - 2
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -345,16 +345,19 @@ static void checkChillerStatus(Gpio_out *gpio)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
     static ChillerInfo _chiller;
+    struct FanModuleData* ShmFanModuleData = (struct FanModuleData*)GetShmFanModuleData();;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[0].withChiller = TRUE;
     }
 
     if ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[1].withChiller = TRUE;
     }
 
     if (chillerCount == 0) {
@@ -362,7 +365,9 @@ static void checkChillerStatus(Gpio_out *gpio)
         return;
     }
 
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++) {
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        if (!ShmDcCommonData->pGunInfo[gunIndex].withChiller)
+            continue;
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
@@ -380,6 +385,7 @@ static void checkChillerStatus(Gpio_out *gpio)
                 if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
                 {
                     pChillerInfo->ChillerSwitch = NO;
+                    ShmFanModuleData->SetFan1Speed = 0;
                 }
             }
             else
@@ -411,12 +417,15 @@ static void checkChillerStatus(Gpio_out *gpio)
     }
 
     uint8_t _chillerNeedOn = NO;
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++)
     {
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
         if(pChillerInfo->ChillerSwitch == YES)
         {
             _chillerNeedOn = YES;
+            if (chillerCount >= 2) {
+                ShmFanModuleData->SetFan1Speed = 7000;
+            }
         }
     }
 

+ 78 - 9
EVSE/Projects/DD360Audi/Apps/ReadCmdline.c

@@ -210,11 +210,15 @@ void RunStatusProc(char *v1, char *v2)
 
         if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
             // get
-            printf ("index = %x, status = %x (%d)\n",
+            printf ("index = %x, status = %x (%d) Reservation is :%s\n",
                     _index,
                     pDcChargingInfo->SystemStatus,
-                    pDcChargingInfo->IsAvailable);
-            printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
+                    pDcChargingInfo->IsAvailable,
+                    ShmDcCommonData->pGunInfo[_index].ReservationStatus ? "trigger" : "expired");
+            if (ShmDcCommonData->pGunInfo[_index].ReservationStatus)
+                printf("Reservation idTag:%s\n", ShmDcCommonData->pGunInfo[_index].ReservationID);
+
+            printf("SystemTimeoutFlag = %d, PageIndex = %d\n",
                     pSysInfo->SystemTimeoutFlag, pSysInfo->PageIndex);
         } else {
             // set
@@ -335,6 +339,21 @@ void GetFwVerProc(void)
                      "      exit | c | C\n"
                      "      help | ? | h\n";
 
+
+    printf("ModelName = %s\r\n", pSysConfig->ModelName);
+    printf("DC Main Version = %s \n", pSysInfo->CsuRootFsFwRev);
+    printf("407 FW Version = %s\n", ShmPrimaryMcuData->version);
+    printf("Gun 0 FW Version = %s \n", pSysInfo->Connector1FwRev);
+    printf("Gun 1 FW Version = %s \n", pSysInfo->Connector2FwRev);
+    printf("Relay Board Version = %s \n", pSysInfo->RelayModuleFwRev);
+    printf("FAN Version = %s \n", pSysInfo->FanModuleFwRev);
+    printf("LED Version = %s \n", pSysInfo->LedModuleFwRev);
+    printf("LCM FW Version = V.%03d \n", ShmDcCommonData->LcmFwVersion);
+    printf("Dispenser Network Information checked: IP = % s Netmask = % s, Gateway = % s \n",
+        pSysConfig->Eth0Interface.EthIpAddress,
+        pSysConfig->Eth0Interface.EthSubmaskAddress,
+        pSysConfig->Eth0Interface.EthGatewayAddress);
+    /*
     while (isContinue) {
         if (readCmdKey(CMD_KEY_WAIT) == NO) {
             continue;
@@ -379,6 +398,7 @@ void GetFwVerProc(void)
         }
 
     }//while
+    */
 }
 
 void CreateOneError(char *v1)
@@ -476,6 +496,7 @@ void GetSystemInfo()
     printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
             pSysConfig->MaxChargingPower,
             pSysConfig->MaxChargingCurrent);
+    pSysConfig->ShowInformation = YES;
 }
 
 void ChangeGunNum()
@@ -538,6 +559,7 @@ void SetDebugMode(char *v1)
     int mode = atoi(v1);
 
     ShmDcCommonData->debugflag = mode;
+    pSysConfig->ShowInformation = mode;
     printf("Set Debug Mode:%d\n" , ShmDcCommonData->debugflag);
 }
 
@@ -723,6 +745,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         return;
     }
     //kill ev task
+    ShmDcCommonData->debugflag = YES;
     system("killall Module_EvComm");
 
     pSysInfo->CurGunSelected = _GunIndex;
@@ -947,7 +970,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             pDcChargingInfo->PresentChargingPower = 0;
 
             if (stopChg == pSysConfig->TotalConnectorCount) {
-
+                ShmDcCommonData->debugflag = NO;
                 system("/root/Module_EvComm &");
                 sleep(3);
 
@@ -1194,6 +1217,7 @@ static void writeOTPTemp(void)
         usleep(sleepTime);
     }//while
 }
+
 void writeChillerStatus(char *v1)
 {
     if (ShmDcCommonData->debugflag == YES) {
@@ -1205,6 +1229,35 @@ void writeChillerStatus(char *v1)
     } else
         printf("Please open Debug mode\n");
 }
+
+void showNetworkPage(char* v1)
+{
+    ShmDcCommonData->showNetPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showNetPackage)
+        printf("Show Network Package on\n");
+    else
+        printf("Show Network Package off\n");
+}
+
+void showCANBUSPage(char* v1)
+{
+    ShmDcCommonData->showCanPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showCanPackage)
+        printf("Show CAN Bus Package on\n");
+    else
+        printf("Show CAN Bus Package off\n");
+}
+void setSystemTime(char* date,char* time)
+{
+    char _setTime[30];
+    char cmdBuf[50];
+    sprintf(_setTime, "%s %s", date, time);
+    printf("Set Timer:%s", _setTime);
+    sprintf((char*)cmdBuf, "date -u -s \"%s\" >> /dev/null &", _setTime);
+    system((char*)cmdBuf);
+    system("hwclock -w -u");
+    system("hwclock -s");
+}
 static void writeGunAndChillerTemp(void)
 {
     uint8_t _GunIndex = 0;
@@ -1280,7 +1333,16 @@ static void writeGunAndChillerTemp(void)
         usleep(sleepTime);
     }//while
 }
+void ShowPowerConsumption(char* v1)
+{
+    printf("Dispenser Gun0 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[0].PowerConsumption);
+    printf("Dispenser Gun1 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[1].PowerConsumption);
 
+    printf("Power Consumption Gun1:%.4f, Gun2:%.4f, Gun3:%.4f, Gun4:%.4f", ShmDcCommonData->pConsumption.Gun1_Consumption,
+        ShmDcCommonData->pConsumption.Gun2_Consumption,
+        ShmDcCommonData->pConsumption.Gun3_Consumption,
+        ShmDcCommonData->pConsumption.Gun4_Consumption);
+}
 int main(void)
 {
     uint8_t _GunIndex = 0;
@@ -1305,7 +1367,10 @@ int main(void)
                      "       tempW                             : write connector header and Chiller temperature\r\n"
                      "       tempR                             : print connector header and chiller temperature\r\n"
                      "       OTP                               : Write OTP temperature\r\n"
-                     "       chiller                           : set chiller on/off"
+                     "       chiller                           : set chiller on/off\r\n"
+                     "       netdump                           : show network package\r\n"
+                     "       candump                           : show can package\r\n"
+                     "       powerconsumption                  : Show Power Consumption\n"
                      "\r\n";
 
     if (CreateAllCsuShareMemory() == FAIL) {
@@ -1456,10 +1521,6 @@ int main(void)
             }
             SetChargingInfoCCID(newString[1], newString[2]);
         } else if (strcmp(newString[0], "strchg") == 0) {
-            if (ShmDcCommonData->debugflag == NO ) {
-                printf("Please Open debug mode\n");
-                continue;
-            }
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             if (strcmp(newString[1], "auto") == 0) {
                 newString[2][0] = 0;
@@ -1482,6 +1543,14 @@ int main(void)
             writeOTPTemp();
         } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
             writeChillerStatus(newString[1]);
+        } else if (strcmp(newString[0], "netdump") == 0) { //印出網路封包
+            showNetworkPage(newString[1]);
+        } else if (strcmp(newString[0], "candump") == 0) { //印出網路封包
+            showCANBUSPage(newString[1]);
+        } else if (strcmp(newString[0], "time") == 0) {  //設定系統時間
+            setSystemTime(newString[1], newString[2]);
+        } else if (strcmp(newString[0], "powerconsumption") == 0) { // Power Consumption
+            ShowPowerConsumption(newString[1]);
         } else {
             printf("%s\n", usageMsg);
         }

+ 5 - 1
EVSE/Projects/DD360Audi/Apps/SelectGun/SelectGun.h

@@ -61,7 +61,11 @@ typedef struct StPricesInfo {
     //float TotalCost;            //unit = 0.01 dollar, value / 100
     float Balance;              //unit = 0.01 dollar, value / 100
     //float DefaultPrices;        //unit = 0.01 dollar, value / 100
-    uint8_t Reserved[4];
+    float Discount;
+    int TransactionId;
+    float EnergyCost;
+    float ParkingFee;
+    float RemainAmount;
 } PricesInfo;
 
 //typedef struct StOperativeInfo {

+ 44 - 7
EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c

@@ -38,6 +38,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 
 static SelectGunInfo *ShmSelectGunInfo = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
@@ -300,6 +301,15 @@ void *GetShmOCPP16Data(void)
     return ShmOCPP16Data;
 }
 
+void* GetShmOCPP20Data(void)
+{
+    if (ShmOCPP20Data == NULL) {
+        return NULL;
+    }
+
+    return ShmOCPP20Data;
+}
+
 void *GetShmSelectGunInfo(void)
 {
     if (ShmSelectGunInfo == NULL) {
@@ -604,6 +614,21 @@ int InitOCPPShmMem(void)
     return PASS;
 }
 
+int InitOCPP20ShmMem(void)
+{
+    int MeterSMId = FAIL;
+
+    if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) {
+        log_info("Get OCPP20 share memory error");
+        return FAIL;
+    } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void*)-1) {
+        log_info("Create OCPP20 share memory error");
+        return FAIL;
+    }
+
+    return PASS;
+}
+
 int InitLEDShmMem(void)
 {
     int MeterSMId = FAIL;
@@ -905,16 +930,15 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
         }
         break;
 
+    case 'V': // Liquid CCS1 combo
+    case 'F': // Liquid CCS2 combo
     case 'T': // Rema CCS1
     case 'D': // Rema CCS2
     case 'U': // CCS1 combo
     case 'E': // CCS2 combo
-    case 'V': // Liquid CCS1 combo
-    case 'F': // Liquid CCS2 combo
     case 'M': // 80A CCS2
     case 'N': // 80A CCS1
-    case 'P': // Phoenix CCS2 500A 水冷
-    case 'R': // Phoenix CCS1 500A 水冷
+    case 'P': // 急電弓
         if (CCS_QUANTITY > gGunIndexInfo.CcsIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->CcsChargingData[gGunIndexInfo.CcsIndex];
 
@@ -934,16 +958,25 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
                 gGunIndexInfo.CcsIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
-            if(typeValue == 'P')
-            {
+            if(typeValue == 'P') {
                 pDcChargingInfo->PantographFlag = YES;
-            }
+            } else if (typeValue == 'V') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Liquid;
+            } else if (typeValue == 'F') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Liquid;
+            } else if (typeValue == 'T' || typeValue == 'U' || typeValue == 'N') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Natural;
+            } else if (typeValue == 'D' || typeValue == 'E' || typeValue == 'M') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Natural;
+            } else
+                pDcChargingInfo->CCSGunType = _TYPE_CCS_NONE;
         } else {
             result = false;
         }
         break;
 
     case 'G':  // GBT DC
+    case 'B': // GBT YG PT100
         if (GB_QUANTITY > gGunIndexInfo.GbIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->GbChargingData[gGunIndexInfo.GbIndex];
 
@@ -1114,6 +1147,10 @@ int CreateAllCsuShareMemory(void)
         return ret;
     }
 
+    if ((ret = InitOCPP20ShmMem()) == FAIL) {
+        return ret;
+    }
+
     if ((ret = InitSelectGunShmMem()) == FAIL) {
         return ret;
     }

+ 1 - 0
EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.h

@@ -42,6 +42,7 @@ void *GetShmSysInfoData(void);
 void *GetShmSysWarningInfo(void);
 
 void *GetShmOCPP16Data(void);
+void* GetShmOCPP20Data(void);
 
 void *GetShmCHAdeMOData(void);
 void *GetShmGBTData(void);

+ 1 - 0
EVSE/Projects/DD360ComBox/Apps/CSU/Ethernet.c

@@ -194,6 +194,7 @@ void InitEthernet(void)
     //system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up");
 
     if (pSysConfig->Eth0Interface.EthDhcpClient == 0) {
+        system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
         sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &",
                 pSysConfig->SystemId);
         system(tmpbuf);

+ 10 - 7
EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c

@@ -23,7 +23,7 @@ typedef struct StLedConfig {
     uint8_t AcContactor: 1;                     //bit 6,    H: ON,      L:OFF
     uint8_t Reserved: 1;                        //bit 7 reserved
 } LedConfig;
-
+time_t showInfoTimer;
 //------------------------------------------------------------------------------
 static uint8_t checkCabinetEthConnectState(LedConfig *ledConfig)
 {
@@ -217,6 +217,7 @@ static void checkChargingInfoByDC(uint8_t systemStatus)
 
     switch (systemStatus) {
     case S_IDLE:
+    case S_RESERVATION:
         if (isDetectPlugin()) {
             _DetectPlugInTimeout();
             StopSystemTimeoutDet();
@@ -436,12 +437,14 @@ void ChkPrimaryStatus(void)
     }
 
     //DS60-120 add
-    //if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
-    //        ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
-    //    pSysConfig->ShowInformation = YES;
-    //} else {
-    //    pSysConfig->ShowInformation = NO;
-    //}
+    if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
+            ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) {
+        pSysConfig->ShowInformation = YES;
+        showInfoTimer = time((time_t*)NULL);
+    } else {
+        if ( (time((time_t*)NULL) - showInfoTimer) > 3 )
+            pSysConfig->ShowInformation = NO;
+    }
 
     if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS &&
             !leftBtnPush &&

+ 19 - 5
EVSE/Projects/DD360ComBox/Apps/CSU/RFID.c

@@ -16,7 +16,7 @@
 static char *rfidPortName = "/dev/ttyS2";
 
 static bool isCardScan = false;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 static bool canStartCharging(void)
 {
@@ -140,7 +140,8 @@ static void UserScanFunction(void)
             stopReq = i;
         }
 
-        if ((pDcChargingInfo->SystemStatus == S_IDLE &&
+        if (((pDcChargingInfo->SystemStatus == S_IDLE ||
+            pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                 pDcChargingInfo->IsAvailable == YES) ||
                 (pGunIndexInfo->AcGunIndex > 0 &&
                  pAcChargingInfo->SystemStatus == S_IDLE &&
@@ -229,7 +230,7 @@ static void UserScanFunction(void)
             strcpy((char *)pSysConfig->UserId, "");
         } else if ((pGunIndexInfo->AcGunIndex > 0 &&
                     pSysInfo->CurGunSelectedByAc == DEFAULT_AC_INDEX) ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+                   pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) {
             log_info("// LCM => Authorizing");
 
             setSelGunWaitToAuthor(pSysInfo->CurGunSelected);
@@ -266,6 +267,7 @@ void ScannerCardProcess(void)
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
     SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
 
     if (!isDetectPlugin() &&
             !isCardScan &&
@@ -299,6 +301,7 @@ void ScannerCardProcess(void)
                     // LCM => Authorize fail
                     pSysInfo->SystemPage = _LCM_AUTHORIZ_FAIL;
                     strcpy((char *)pSysConfig->UserId, "");
+                    ShmDcCommonData->AuthroizeType = IdTokenType_Central;
                 }
 
             } ClearAuthorizedFlag();
@@ -364,9 +367,10 @@ void CreateRfidFork(void)
         int fd = -1;
         int isContinue = 1;
         RFID rfid = {0};
+        int module_type = MODULE_EWT;
         fd = InitialRfidPort();
         struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-
+        ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
         //log_info("RFID fork Child's PID is %d", getpid());
 
         while (isContinue) {
@@ -378,7 +382,7 @@ void CreateRfidFork(void)
                 continue;
             }
 
-            if (getRequestCardSN(fd, 0, &rfid) == false) {
+            if (getRequestCardSN(fd, module_type, &rfid) == false) {
                 continue;
             }
 
@@ -455,6 +459,16 @@ void CreateRfidFork(void)
                 }
             }
             log_info("card number = %s", pSysConfig->UserId);
+            if (strlen((char*)pSysConfig->UserId) != 0) {
+                ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
+            }
+            if (rfid.cardType == ISO14443A) {
+                sethaltCard(fd, module_type);
+            } else if (rfid.cardType == IS014443B) {
+
+            } else if (rfid.cardType == FELICA) {
+
+            }
         }
     }
 }

+ 162 - 248
EVSE/Projects/DD360ComBox/Apps/CSU/main.c

@@ -61,6 +61,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
 
 static struct ChargingInfoData *pDcChargingInfo = NULL;
@@ -82,8 +83,8 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.20.00.0000.00"; // "V0.16.00.0000.00";
-char* DebugVersion = "v1.20.0";
+char *fwVersion = "V1.21.00.0000.00"; // "V0.16.00.0000.00";
+char* DebugVersion = "v1.21.5";
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -199,7 +200,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(LEFT_GUN_NUM);
@@ -218,7 +221,9 @@ void destroySelGun(uint8_t curGun)
     if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun != SEL_GUN_RELEASE)) {
         if (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM ||
                 ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR) {
+#ifdef DD360Audi
             changeLcmPage(_LCM_SELECT_GUN);
+#endif
         }
         ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE;
         StopGunInfoTimeoutDet(RIGHT_GUN_NUM);
@@ -233,6 +238,7 @@ void destroySelGun(uint8_t curGun)
             ShmSelectGunInfo->PricesInfo[curGun].Balance = FAIL_BALANCE_PRICES;
         }
     }
+
 }
 
 static int waitRightGunPlugIt(uint8_t curGun)
@@ -398,52 +404,105 @@ static void checkGunOTPState(uint8_t gunIndex)
     //log_info("OTP:%d OTPR%d",pSysInfo->OTPTemp,pSysInfo->OTPTempR);
     //水冷機溫度檢測
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
-        if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
-            if (pDcChargingInfo->ChillerTemp >= pSysInfo->OTPTemp ) {
-                if (((gunIndex == 0) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                         ||
-                    ((gunIndex == 1) &&
-                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-                   ) {
-                    RecordAlarmCode(gunIndex, "012323");
+        if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
+            // 單水冷機
+            // Chiller OTP
+            if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
-                }
-                else
-                {
+                    RecordAlarmCode(gunIndex, "012323");
+                } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
                 }
-            } else if (pDcChargingInfo->ChillerTemp != 0 &&
-                       pDcChargingInfo->ChillerTemp < pSysInfo->OTPTempR) {
-                //ResetChargerAlarmCode(gunIndex, "012323");
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-        } else {
-            // 沒接上 Sensor or 異常
-            //RecordAlarmCode(gunIndex, "011038");
-            //ResetChargerAlarmCode(gunIndex, "012323");
-            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-            if (((gunIndex == 0) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
-                     ||
-                ((gunIndex == 1) &&
-                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
-                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
-               ) {
+            // Chiller Tube OTP
+            if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-            }
-            else
-            {
+            } else {
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                    RecordAlarmCode(gunIndex, "012332");
+                } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR &&
+                    ShmDcCommonData->SystemTemp[3] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                }
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
+        } else {
+            // 雙水冷機
+            if (gunIndex == LEFT_GUN_NUM) {
+                if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+                    } else if (ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            } else {
+                if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                        RecordAlarmCode(gunIndex, "012323");
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+                if (ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
+                    // 溫度為255時判斷Sensor fail
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+                } else {
+                    //判斷OTP
+                    if (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                        RecordAlarmCode(gunIndex, "012332");
+
+                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
+                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
+                    }
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+                }
+            }
         }
 
-        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
-        {
+        if (pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES) {
             RecordAlarmCode(gunIndex, "011037");
         }
     }
@@ -466,6 +525,15 @@ static void checkGunOTPState(uint8_t gunIndex)
             //ResetChargerAlarmCode(gunIndex, "012229");
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
+            if  ((gunIndex == 0) &&
+                    (strncmp((char *)&pSysConfig->ModelName[7], "J", 1) == 0)) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            } else if ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "J", 1) == 0) )) {
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
+            }
         }
         break;
 
@@ -1539,11 +1607,7 @@ uint8_t isPrechargeStatus_ccs(uint8_t gunIndex)
     uint8_t result = 0x00;
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
-        result = ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;
-    }
-
-    return result;
+    return ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus;;
 }
 
 bool isEvStopCharging_ccs(uint8_t gunIndex)
@@ -1643,7 +1707,7 @@ void _DetectPlugInTimeout(void)
 	//pSysInfo->SystemPage = _LCM_COMPLETE;
 	setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING);
 #elif DD360 || DD360Combox
- 	setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE);
+ 	setChargerMode(pSysInfo->CurGunSelected, S_IDLE);
 #endif
     systemPageRestoreInit();
 }
@@ -3801,6 +3865,7 @@ static void autoStartCharging(uint8_t gunIndex)
                     ChangeGunSelectByIndex(gunIndex);
                     confirmSelGun(gunIndex);
                     pDcChargingInfo->isEVCCIDVerify = true;
+                    ShmDcCommonData->AuthroizeType = IdTokenType_MacAddress;
                     pSysInfo->SystemPage = _LCM_AUTHORIZING;
                 }
             } else
@@ -3811,6 +3876,7 @@ static void autoStartCharging(uint8_t gunIndex)
             ChangeGunSelectByIndex(gunIndex);
             confirmSelGun(gunIndex);
             pSysInfo->SystemPage = _LCM_AUTHORIZING;
+            ShmDcCommonData->AuthroizeType = IdTokenType_NoAuthorization;
         }
         if (strcmp( (char *)pSysConfig->UserId , OldUseId ) != EQUAL) {
             strcpy((char *)OldUseId, (char *)pSysConfig->UserId);
@@ -4111,9 +4177,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_Chademo:
         // 檢查樁端的 GFD 結果
         if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_chademo(gunIndex) > 6 &&
-                isPrechargeStatus_chademo(gunIndex) < 8
-           ) {
+                isPrechargeStatus_chademo(gunIndex) >= 6) {
             // 當前操作的槍號,進入 Charging
             setChargerMode(gunIndex, MODE_CHARGING);
         }
@@ -4160,8 +4224,7 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
     case _Type_GB:
         // 檢查樁端的 GFD 結果
         //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-        if (sysStatus == S_PREPARING_FOR_EVSE &&
-                isPrechargeStatus_gb(gunIndex) > 6) {
+        if (sysStatus == S_PREPARING_FOR_EVSE && isPrechargeStatus_gb(gunIndex) >= 6) {
             setChargerMode(gunIndex, MODE_CHARGING);
         }
 
@@ -4353,6 +4416,7 @@ int main(void)
     ShmRelayModuleData = (struct RelayModuleData *)GetShmRelayModuleData();
     ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
     ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
+    ShmOCPP20Data = (struct OCPP20Data*)GetShmOCPP20Data();
     ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
 	
@@ -4454,6 +4518,9 @@ int main(void)
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
 
             pDcChargingInfo->IsAvailable = DB_Get_Operactive(_index);
+            if (!DB_Get_PowerConsumption(_index)) {
+                DB_Insert_PowerConsumption(_index, 0);
+            }
         }
         DB_Reboot_Record();
     }
@@ -4484,6 +4551,9 @@ int main(void)
 
     pSysInfo->OTPTemp = GUN_OTP_VALUE;
     pSysInfo->OTPTempR = GUN_OTP_RECOVERY;
+
+    time_t ShowEVStatusTimer[2] = { 0 };
+
     for (;;) {
 
         CheckOcppStatus();
@@ -4582,14 +4652,16 @@ int main(void)
                 CheckSmartChargeProfile(gunIndex);
             }
 
-            //log_info("index = %d, ErrorCode = %s",
-            //         gunIndex,
-            //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-
+            case S_RESERVATION:
                 if (isModeChange(gunIndex)) {
-                    log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    if (pDcChargingInfo->SystemStatus == S_IDLE)
+                        log_info("============================= S_IDLE(%x) ============================= ", gunIndex);
+                    else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                        log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
+                        ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
+                    }
                     pDcChargingInfo->PresentChargedDuration = 0;
                     pDcChargingInfo->RemainChargingDuration = 0;
                     pDcChargingInfo->PresentChargingVoltage = 0;//DS60-120 add
@@ -4598,9 +4670,11 @@ int main(void)
                     strcpy((char *)pDcChargingInfo->StopDateTime, "");
                     strcpy((char *)pDcChargingInfo->StartUserId, "");
                     strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "");
-
+                    
                     //Jerry add
                     memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo));
+                    memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo));
+                    DB_Get_PowerConsumption(gunIndex);
                     ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES;
                     destroySelGun(gunIndex);
                     ResetDetAlarmStatus(gunIndex); //recovery OVP status code
@@ -4611,12 +4685,6 @@ int main(void)
                     ReleaseAlarmCode(gunIndex);
                 }
 
-            case S_RESERVATION:
-                if (isModeChange(gunIndex)) {
-                    log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex);
-                    ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES;
-                }
-
                 if (pDcChargingInfo->IsAvailable == NO) {
                     setChargerMode(gunIndex, MODE_MAINTAIN);
                 }
@@ -4732,11 +4800,17 @@ int main(void)
                     } else if (pSysInfo->OrderCharging == NO_DEFINE) {
                         if (pDcChargingInfo->ConnectorPlugIn == YES &&
                                 pDcChargingInfo->IsAvailable &&
-                                pDcChargingInfo->SystemStatus == S_IDLE &&
+                                (pDcChargingInfo->SystemStatus == S_IDLE ||
+                                    pDcChargingInfo->SystemStatus == S_RESERVATION) &&
                                 //waitSelectGunPlugIt(gunIndex)
                                 (waitRightGunPlugIt(gunIndex) == PASS ||
-                                 waitLeftGunPlugIt(gunIndex) == PASS)
-                           ) {
+                                 waitLeftGunPlugIt(gunIndex) == PASS) ) {
+                            if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
+                                if (strcmp((char*)pSysConfig->UserId, (char*)ShmDcCommonData->pGunInfo[gunIndex].ReservationID) != EQUAL) {
+                                    //log_info("Not Resercation ID");
+                                    continue;
+                                }
+                            }
                             log_info("-----------------2----------------- ");
                             ChangeGunSelectByIndex(gunIndex);
                             AddPlugInTimes(gunIndex);
@@ -4745,6 +4819,7 @@ int main(void)
                                      gunIndex,
                                      pDcChargingInfo->StartUserId);
                             strcpy((char *)pSysConfig->UserId, "");
+                            ShmDcCommonData->AuthroizeType = IdTokenType_ISO14443;
                             // 當前操作的槍號,進入 Preparing
                             setChargerMode(gunIndex, MODE_REASSIGN_CHECK);
                             ClearDetectPluginFlag();
@@ -4758,10 +4833,6 @@ int main(void)
                         // AUDI_LCM_CHANGE
                         pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG;
                     }
-                } else if (pDcChargingInfo->SystemStatus == S_RESERVATION) {
-                    if (!isReservationExpired(gunIndex)) {
-                        pDcChargingInfo->SystemStatus = S_IDLE;
-                    }
                 } /*else if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE &&
                            (pDcChargingInfo->ConnectorPlugIn == YES &&
                             pDcChargingInfo->IsAvailable)
@@ -4775,7 +4846,8 @@ int main(void)
                         ClearDetectPluginFlag();
                         continue;
                     }
-                } */else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
+                } */
+                else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && 
                         pSysInfo->CurGunSelected == gunIndex && !pDcChargingInfo->isEVCCIDVerify) {
                     systemPageRestoreInit();
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
@@ -4860,7 +4932,7 @@ int main(void)
 
                 if (ShmPsuData->SystemPresentPsuQuantity > 0 &&
                         ShmPsuData->SystemAvailablePower > 10 &&
-                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 5000000) {
+                        GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 1000000) {
                     setChargerMode(gunIndex, MODE_PREPARE_FOR_EV);
                 }
 
@@ -4931,52 +5003,7 @@ int main(void)
                 }
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 檢查樁端的 GFD 結果
-                    if (isPrechargeStatus_chademo(gunIndex) > 5 &&
-                            isPrechargeStatus_chademo(gunIndex) < 8) {
-                        // 當前操作的槍號,進入 Charging
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    // 檢查樁端的 GFD 結果
-                    //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) {
-                    if (isPrechargeStatus_gb(gunIndex) > 9) {
-                        setChargerMode(gunIndex, MODE_CHARGING);
-                    }
 
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 檢查樁端的 GFD 結果
-                    if ((pDcChargingInfo->GroundFaultStatus == GFD_PASS ||
-                            pDcChargingInfo->GroundFaultStatus == GFD_WARNING)) {
-                        setChargerMode(gunIndex, MODE_CCS_PRECHARGE_STEP0);
-                    }
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-                }
-#endif //0
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
 
                 // LCM => Pre-charging
@@ -5003,64 +5030,12 @@ int main(void)
                 pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]);
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012289");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    }
-                    //else if (isPrechargeStatus_gb(gunIndex) == 10 &&
-                    //           (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //             pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //            (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //             pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL))
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012290");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    }
-                    //else if (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
-                    //            pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) ||
-                    //           (pDcChargingInfo->PresentChargedDuration >= 10 &&
-                    //            pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)
-                    //          ) {
-                    //    // UVP
-                    //    RecordAlarmCode(gunIndex, "012288");
-                    //    ChargingTerminalProcess(gunIndex);
-                    //}
-                    else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
+
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime) >= 5) {
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
-#endif //0
 
                 if ((evBoardStopState = isEvBoardStopChargeFlag(gunIndex)) > 0) {
                     // 板端要求停止 (錯誤)
@@ -5122,86 +5097,21 @@ int main(void)
 
                     //log_info ("terminating......................... %x ", gunIndex);
                     StopGunInfoTimeoutDet(gunIndex);
+                    ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
 
                 //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-#if 0
-                if (pDcChargingInfo->Type == _Type_Chademo) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012234");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012296");
-                    }
-
-                    //if (isEvStopCharging_chademo(gunIndex) == YES ||
-                    //        isPrechargeStatus_chademo(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //log_info("************ GB lock Status = %d, status = %d ",
-                    //         isEvStopCharging_gb(gunIndex),
-                    //         isPrechargeStatus_gb(gunIndex));
-
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012236");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012298");
-                    }
 
-                    //if (isEvStopCharging_gb(gunIndex) == YES ||
-                    //        isPrechargeStatus_gb(gunIndex) <= 0) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
-                    //if (isEvStopCharging_chademo(gunIndex) == YES) {
-                    //    /*+++ 20200908, vern, disable it for DD360 +++*/
-                    //    /*if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL)
-                    //            strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local");*/
-                    //    /*--- 20200908, vern, disable it for DD360 ---*/
-                    //}
-
-                    if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
-                        // GFD 錯誤停止
-                        RecordAlarmCode(gunIndex, "012235");
-                    } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
-                        // GFD 警告
-                        RecordAlarmCode(gunIndex, "012297");
-                    }
-
-                    //if (isEvStopCharging_ccs(gunIndex) == YES &&
-                    //        (isPrechargeStatus_ccs(gunIndex) >= 53 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 0  ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 13 ||
-                    //         isPrechargeStatus_ccs(gunIndex) == 14)) {
-                    //    setChargerMode(gunIndex, MODE_COMPLETE);
-                    //}
-                }
-#endif //0
                 if (pDcChargingInfo->SystemStatus == S_ALARM) {
                     if (pDcChargingInfo->ConnectorPlugIn == NO &&
                             GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                        setChargerMode(gunIndex, MODE_IDLE);
+                        if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                            setChargerMode(gunIndex, MODE_RESERVATION);
+                        } else {
+                            setChargerMode(gunIndex, MODE_IDLE);
+                        }
                     }
                 } else {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
@@ -5244,9 +5154,13 @@ int main(void)
 
                 if (pDcChargingInfo->ConnectorPlugIn == NO &&
                         GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
-                    setChargerMode(gunIndex, MODE_IDLE);
+                    if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
+                        setChargerMode(gunIndex, MODE_RESERVATION);
+                    } else {
+                        setChargerMode(gunIndex, MODE_IDLE);
+                    }
                     destroySelGun(gunIndex); //Jerry add
-#ifdef defined DD360 || defined DD3660ComBox
+#if defined DD360 || defined DD3660ComBox
 					//pSysInfo->SystemPage = _LCM_IDLE;
                     connectorPageRestoreIdle();
 #endif

+ 112 - 6
EVSE/Projects/DD360ComBox/Apps/Config.h

@@ -135,11 +135,17 @@ enum _GUN_TYPE {
     _Type_GB,
     _Type_AC,
 };
-
+enum _CCS_GUN_TYPE {
+    _TYPE_CCS_NONE  = 0,
+    _TYPE_CCS1_Natural,
+    _TYPE_CCS1_Liquid,
+    _TYPE_CCS2_Natural,
+    _TYPE_CCS2_Liquid,
+};
 enum _LCM_INDEX {
-    _LCM_INIT          = 0x00,
-    _LCM_IDLE          = 0x01,
-    _LCM_AUTHORIZING   = 0x02,
+    _LCM_INIT = 0x00,
+    _LCM_IDLE = 0x01,
+    _LCM_AUTHORIZING = 0x02,
     _LCM_AUTHORIZ_COMP = 0x03,
     _LCM_AUTHORIZ_FAIL = 0x04,
     _LCM_WAIT_FOR_PLUG = 0x05,
@@ -147,9 +153,13 @@ enum _LCM_INDEX {
     _LCM_CHARGING      = 0x07,
     _LCM_COMPLETE      = 0x08,
     _LCM_FIX           = 0x09,
+#ifdef DD360Audi
     _LCM_SELECT_GUN    = 0x0A,
     _LCM_EMERGENCY     = 0x0B,
     _LCM_DISCONNECT    = 0x0C,
+#else
+    _LCM_EMERGENCY     = 0x0A,
+#endif
     _LCM_NONE          = 0xFF,
 };
 
@@ -267,7 +277,22 @@ enum _CCS_TYPE {
     _CCS_TYPE_CCS1 = 0,
     _CCS_TYPE_CCS2 = 1,
 };
-
+enum _WEATHER_TYPE {
+	_WEATHER_TYPE_SUN = 1,
+	_WEATHER_TYPE_CLOUDY,
+	_WEATHER_TYPE_RAIN,
+	_WEATHER_TYPE_THUNDER,
+	_WEATHER_TYPE_SNOW,
+	_WEATHER_TYPE_FOG,
+};
+enum _CREDITCARD_STATUS {
+	_CREDITCARD_IDLE,
+	_CREDITCARD_PREAUTH,
+	_CREDITCARD_PREAUTHCOMPLETE,
+	_CREDITCARD_CANCEL,
+	_CREDITCARD_SETTLEMENT,
+	_CREDITCARD_START,
+};
 //------------------------------------------------------------------------------
 //struct StructMeter {
 //    float curMeterValue;
@@ -347,7 +372,8 @@ typedef union {
     struct {
         uint8_t ChillerOTP: 1;            //chiller Temperature OVP
         uint8_t ChillerTempSensorFail: 1; //Chiller temperature sensor failure
-        uint8_t Reserved: 6;
+        uint8_t ChillerTubeOTP : 1;
+        uint8_t Reserved: 5;
     } StatusBit;
 } ChillerTempErr;
 
@@ -363,6 +389,75 @@ typedef struct StPcPsuOutput { //from power cabinet PSU output
     uint16_t Current;
 } PcPsuOutput;
 
+typedef struct StPowerConsumptionInfo {
+    float Gun1_Consumption;
+    float Gun2_Consumption;
+    float Gun3_Consumption;
+    float Gun4_Consumption;
+} PowerConsumptionValue;
+
+typedef struct StPowConsumValue {
+    uint32_t Gun1_Consumption;
+    uint32_t Gun2_Consumption;
+    uint32_t Gun3_Consumption;
+    uint32_t Gun4_Consumption;
+} PowConsumValue;
+
+typedef struct StGunInfo {
+    int ConnectorID;
+    char ReceiptInfo[255];
+    int finalcost_flag;
+    time_t EVLoseTimer;
+    uint8_t EVLoseFlag;
+    char ReservationID[32];
+    uint8_t ReservationStatus;
+    char UserPriceString[255];
+    float PowerConsumption;
+    time_t RecordEnergyTime;
+    char ChargeStartTime[32];
+    char ChargeStopTime[32];
+    char ChargeDuration[32];
+    uint8_t withChiller;      //是否有水冷機
+} GunInfo;
+
+typedef struct Psu_VersionInfo{
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PsuVerInfo;
+
+enum _LCM_UPGRADE_RESULT {
+    _LCM_UPGRADE_RESULT_WAIT = 0,
+    _LCM_UPGRADE_RESULT_PASS,
+    _LCM_UPGRADE_RESULT_FAIL,
+};
+
+typedef struct stTransInfo
+{
+	unsigned char TransDate[6];	//交易日期
+	unsigned char TransTime[6];	//交易時間
+	unsigned char ROC[12];		//EDC簽單調閱編號 (左靠右補空白)
+	unsigned char ApprovalNo[9];		//授權碼[信用卡退貨交易] (左靠右補空白)
+	unsigned char StoreId[18];		//櫃號,機號,發票號碼(左靠右補空白)
+	unsigned char RRN[12];		//信用卡交易序號
+	unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+	unsigned char TransAmount[12];		//交易金額
+	unsigned char VemData[64];		//無人自助設備交易資訊 交易別31/32 (預授權完成/預授權取消) 必要欄位 資訊來源為交易別13 (預授權)的回傳
+}TransInfo;
+
+typedef struct stRecordTransactionInfo
+{
+	int TransactionId;
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    unsigned char ApprovalNo[9];
+    unsigned char CardNo[20];		//卡號(左靠右補空白),卡號部份隱藏
+    unsigned char VemData[64];
+    float Amount;
+    unsigned char IsUpload; // 0: not upload, 1: uploaded
+    unsigned char res;
+}RecordTransactionInfo;
+
 typedef struct StDcCommonInfo {
     uint8_t RebootCount;
     uint8_t CcsVersion;
@@ -382,6 +477,17 @@ typedef struct StDcCommonInfo {
     uint8_t chillerCtrl;
     uint8_t debugflag;
     uint8_t LcmFwVersion;
+    int TZOffset;
+    uint8_t AuthroizeType; // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
+    char QRCodeString[255];
+    char DefaultPriceString[255];
+    PowerConsumptionValue pConsumption;
+    int WeatherID;
+    float Temperature;
+    int Location;
+    GunInfo pGunInfo[2];
+    uint8_t showNetPackage;
+    uint8_t showCanPackage;
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 113 - 1
EVSE/Projects/DD360ComBox/Apps/DataBase/DataBase.c

@@ -14,7 +14,7 @@
 
 //------------------------------------------------------------------------------
 static sqlite3 *localDb;
-
+static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
 //===============================================
 // SQLite3 related routine
@@ -59,6 +59,11 @@ int DB_Open(void)
                             "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, "
                             "`rebootDatetime` TEXT NOT NULL, unique(rebootDatetime) on conflict replace);";
 
+    char *createPowerConsumption = "CREATE TABLE IF NOT EXISTS power_consumption( "
+                         "idx INTEGER PRIMARY KEY AUTOINCREMENT, "
+                         "connector TEXT, "
+                         "val TEXT);";
+
     if (sqlite3_open(DB_FILE, &localDb)) {
         result = FAIL;
         log_info( "Can't open database: %s", sqlite3_errmsg(localDb));
@@ -88,6 +93,14 @@ int DB_Open(void)
             log_info( "Opened local record table successfully");
         }
 
+        //DS60-120
+        if (sqlite3_exec(localDb, createPowerConsumption, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Create power consumption record table error message: %s", errMsg);
+        } else {
+            log_info("Opened power consumption record table successfully");
+        }
+
         if (sqlite3_exec(localDb, createrebootSql, 0, 0, &errMsg) != SQLITE_OK) {
             result = FAIL;
             log_info( "Create reboot record table error message: %s", errMsg);
@@ -99,6 +112,7 @@ int DB_Open(void)
         sqlite3_close(localDb);
     }
 
+    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     return result;
 }
 
@@ -222,6 +236,104 @@ int DB_Get_Operactive(uint8_t gunIndex)
     return result;
 }
 
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully (%f).", energy);
+        sprintf(sqlStr,"insert into power_consumption (connector, val) values (%d, %f);",
+            gunIndex,
+            energy); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("Insert power consumption error message: %s", errMsg);
+        } else {
+            log_info("Insert connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy)
+{
+    uint8_t result = false;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    srand(time(NULL));
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        //log_info("Local charging record database open successfully.");
+        sprintf(sqlStr,"update power_consumption set val = %f where connector = %d; ",
+                        energy,
+                        gunIndex); //DS60-120 add
+        //log_info("sqlStr= %s", sqlStr);
+        if (sqlite3_exec(localDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK) {
+            result = FAIL;
+            log_info("update config error message: %s", errMsg);
+        } else {
+            //log_info("update connector-%d config item PowerComsumption to %f", gunIndex, energy);
+        }
+
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+int DB_Get_PowerConsumption(uint8_t gunIndex)
+{
+    uint8_t result = true;
+    char* errMsg = NULL;
+    char sqlStr[1024];
+    char** rs;
+    int  rows, cols;
+
+    //sprintf(sqlStr, "select * from config where IsAvailable='IsAvailable' and connector=%d;", gunIndex);
+    sprintf(sqlStr, "select * from power_consumption where connector=%d;", gunIndex); //DS60-120 add
+    //DEBUG_INFO("sqlStr= %s", sqlStr);
+
+    if (sqlite3_open(DB_FILE, &localDb)) {
+        result = FAIL;
+        log_info("Can't open database: %s", sqlite3_errmsg(localDb));
+        sqlite3_close(localDb);
+    } else {
+        log_info("Local config query database open successfully.");
+        sqlite3_get_table(localDb, sqlStr, &rs, &rows, &cols, &errMsg);
+        if (rows > 0) {
+            for (int idxRow = 1; idxRow <= rows; idxRow++) {
+                ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = atof(rs[(idxRow * cols) + 2]);
+                log_info("Query connector-%d PowerConsumption: %s", gunIndex, rs[(idxRow * cols) + 2]);
+                
+            }
+        } else {
+            log_info("Query connector-%d fail, set default value to operactive.", gunIndex);
+            result = false;
+        }
+
+        sqlite3_free_table(rs);
+        sqlite3_close(localDb);
+    }
+
+    return result;
+}
+
+
 int DB_Reboot_Record(void)
 {
     int result = PASS;

+ 3 - 1
EVSE/Projects/DD360ComBox/Apps/DataBase/DataBase.h

@@ -10,5 +10,7 @@ int DB_Reboot_Record(void);
 //for Module_EventLog
 int CreateEventRecord(void);
 int InsertEventRecord(uint8_t *statusCode);
-
+int DB_Get_PowerConsumption(uint8_t gunIndex);
+int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy);
+int DB_Update_PowerConsumption(uint8_t gunIndex, float energy);
 #endif /* _DATA_BASE_H_ */

+ 5 - 5
EVSE/Projects/DD360ComBox/Apps/Define/define.c

@@ -236,11 +236,11 @@ char AlarmStatusCode[160][6]=
 "012324", // Connector 1 detects abnormal voltage on the output line
 "012325", // Connector 2 detects abnormal voltage on the output line
 "012326", // System task is lost
-"012327", // DC input ovp
+"012327",   // DC input ovp
 "012328",   // DC input uvp
-"012329",   // reserved
-"012330",   // reserved
-"012331",   // reserved
+"012329",   // Psu Can Communication Fault
+"012330",   // Psu Dc to Dc OTP
+"012331",   // Psu Dc to Dc OVP
 "012332",   // reserved
 "012333",   // reserved
 "012334",   // reserved
@@ -255,7 +255,7 @@ char AlarmStatusCode[160][6]=
 "012343",   // reserved
 "012344",   // AC: Meter IC communication timeout
 "012345",   // AC: Pilot negative error
-"012346",   // reserved
+"012346",   // Psu Communication error with CSU
 "012347",   // reserved
 "012348",   // reserved
 "012349",   // reserved

+ 110 - 65
EVSE/Projects/DD360ComBox/Apps/Define/define.h

@@ -186,6 +186,8 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 #define ShmLedBdKey				1011
 #define ShmOcpp20ModuleKey		1012
 #define ShmRelay2BdKey			1013
+#define ShmYesCustomKey         1014
+#define ShmOcppPHModuleKey      1015
 
 #define FaultCodeLength         5
 #define AlarmCodeLength         20
@@ -321,8 +323,15 @@ enum CoreProfile {
      TimeOffsetNextTransition,
      SystemUptimeSec,
      FreeVend,
+     FreeVendIdtag,
      OcppServer,
      MaintainServer,
+     StatusNotificationPeriodically,
+     StatusNotificationInterval,
+     PreAuthAmount,
+     isEnableLocalPowerSharing,
+     PowerSharingServerIP,
+     EVCCID_PREFIX,
      ConfigurationVersion,
 	 _CoreProfile_CNT
 };
@@ -336,10 +345,11 @@ enum OCPP_START_ID_TYPE {
     IdTokenType_Central=0,
     IdTokenType_eMAID,
     IdTokenType_ISO14443,
+    IdTokenType_ISO15693,
     IdTokenType_KeyCode,
     IdTokenType_Local,
-    IdTokenType_NoAuthorization,
-    IdTokenType_ISO15693
+    IdTokenType_MacAddress,
+    IdTokenType_NoAuthorization
 };
 /**************************************************************************************/
 /****structure SysConfigData => shall store the data to NAND flash****************/
@@ -414,8 +424,16 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_NOUSE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct LCD_OVERRIDE
 {
+    unsigned char           connectorId;                // LCD override connector id
     unsigned char           page_index;                 // LCD override page index
     unsigned char           duration;                   // LCD override duration
     unsigned char           isOverideReq:1;             // LCD override request
@@ -448,7 +466,7 @@ struct TTIA
 
 struct LocalSharingInfo
 {
-    unsigned short      AvailableShargingCurrent;       // 0 ~ rating value amp,  Synchronize from local sharing server
+    unsigned short      AvailableShargingCurrent[4];    // 0 ~ rating value amp,  Synchronize from local sharing server
     unsigned char       isConnectedSharingServer:1;     // 0: Disconnected, 1: Connected
 };
 
@@ -464,7 +482,9 @@ typedef union
         unsigned int HardResetStop:1;               // 0: no effect,    1: hard reset stop
         unsigned int SoftResetStop:1;               // 0: no effect,    1: soft reset stop
         unsigned int InvalidIdStop:1;               // 0: no effect,    1: invalid stop when StopTransactionOnInvalidId is true
-        unsigned int res:25;
+        unsigned int RemoteStop:1;                  // 0: no effect,    1: remote stop
+        unsigned int UnlockStop:1;                  // 0: no effect,    1: unlock stop
+        unsigned int res:23;
     }bits;
 }ChargingStop;
 
@@ -557,9 +577,9 @@ struct SysConfigData
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
-	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
+	unsigned char           isEnableLocalPowerSharing;  //0: Disable power sharing  1: Master   2: Slave
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
-    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
+    struct LCD_NOUSE        Legacy_LcdOveride;          // LCD override info (no use anymore)
     struct TTIA             TTIA_Info;                  // TTIA configuration struct
 
     /************PowerCabinet************/
@@ -570,6 +590,7 @@ struct SysConfigData
     unsigned char           MaintainServerURL[512];             // ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
     unsigned char           MaintainServerSecurityProfile;      // Maintain server security profile 0~3
     unsigned char           MaintainServerSecurityPassword[41]; // Maintain server AuthorizationKey for security profile
+    unsigned char           PowerSharingServerIP[512];          // Local power sharing server ip address
 };
 
 struct ChargingInfoData
@@ -609,7 +630,7 @@ struct ChargingInfoData
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
 	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
-	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MaxAddress   7: NoAuthorization
+	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
@@ -685,7 +706,7 @@ typedef struct
     unsigned char       AuthType;                       // 0: _AuthType_None,   1: _AuthType_RFID, 2: _AuthType_RemoteStart
     unsigned char       AuthResult;                     // 0: _AuthResult_None, 1: _AuthResult_Valid,   2: _AuthResult_Invalid
     unsigned char       AuthRequest;                    // 0: no request, 1: authorize request
-    unsigned char       res;
+    unsigned char       AuthIdType;
 }AuthorizingInfoData;
 
 typedef union
@@ -699,26 +720,12 @@ typedef union
         unsigned int MiscNeedAnnouncement:1;            // 0: no need,      1: need send misc command
         unsigned int NeedDispenserVerInfo:1;            // 0: no need,      1: need dispenser to report it's version info
         unsigned int AuthorizeRequest:1;                // 0: idle,         1: requesting                           ( dispenser -> cabinet)
-        unsigned int ConnectorTimeoutConfigRequest:1;   // 0: no request,   1: connector timeout setting            (    ocpp   -> cabinet -> dispenser)
-        unsigned int DefaultPriceConfigRequest:1;       // 0: no request,   1: default price setting                (    ocpp   -> cabinet -> dispenser)
-        unsigned int CurrencyConfigRequest:1;           // 0: no request,   1: currency setting                     (    ocpp   -> cabinet -> dispenser)
-        unsigned int HardwareRebootRequest:1;           // 0: no request,   1: hardware reboot request              (    ocpp   -> cabinet -> dispenser)
         unsigned int HardwareRebootConfirm:1;           // 0: no effect,    1: dispenser confirmed
-        unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
         unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
         unsigned int FirmwareUpdateRequest:1;           // firmware update request
         unsigned int FirmwareUpdateConfirm:1;           // firmware update start
         unsigned int FirmwareUpdateCompleted:1;         // firmware update completed
-        unsigned int BackendStatusRequest:1;            // 0: no request,   1: backend connection status has changed            ( cabinet -> dispenser)
-        unsigned int EthernetStatusRequest:1;           // 0: no request,   1: ethernet connection status has changed           ( cabinet -> dispenser)
-        unsigned int WiFiStatusRequest:1;               // 0: no request,   1: wifi connection status has changed               ( cabinet -> dispenser)
-        unsigned int TelcomModemStatusRequest:1;        // 0: no request,   1: 4g connection status has changed                 ( cabinet -> dispenser)
-        unsigned int BillingStatusRequest:1;            // 0: no request,   1: billing status has changed                       ( cabinet -> dispenser)
-        unsigned int StopButtonStatusRequest:1;         // 0: no request,   1: stop charging button status has changed          ( cabinet -> dispenser)
-        unsigned int AuthModeConfigRequest:1;           // 0: no request,   1: AuthMode Config has changed                      ( cabinet -> dispenser)
-        unsigned int EVCCIDConfigRequest:1;             // 0: no request,   1: EVCCID Config has changed                        ( cabinet -> dispenser)
-        unsigned int LEDIntensityRequest:1;             // 0: no request,   1: LED Intensity has changed                        ( cabinet -> dispenser)
-        unsigned int res:7;
+        unsigned int res:21;
     }bits;
 }DispenserSettingFlag;
 
@@ -735,7 +742,7 @@ struct DispenserModule
     unsigned char   RfidCardNumEndian;          //0: little endian,  1: big endian
     unsigned char   isAPP;                      //for AuthorisationMode=0; 0:false, 1:true
     unsigned char   isQRCode;                   //for AuthorisationMode=0; 0:false, 1:true
-    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true
+    unsigned char   isRFID;                     //for AuthorisationMode=0; 0:false, 1:true; for Noodoe Credit Card +2^1:true
     unsigned char   QRCodeMadeMode;             //for isQRCode=1 ; 0: default	1:customized
     unsigned char   QRCodeContent[128];         //for QRCodeMadeMode=1
 
@@ -794,10 +801,6 @@ struct DispenserInfoData
     }CheckInLog;                                                        // record dispenser checkin status
     unsigned char               ConnectorLog[GENERAL_GUN_QUANTITY];     // record connector quantity of dispenser
     struct ConnectionInfoData   ConnectionInfo[GENERAL_GUN_QUANTITY];
-
-    unsigned short      ConnectorTimeout;           // connector plug in timeout, unit 1s
-    unsigned int        DefaultPrice;               // dispenser default price, unit: 0.01 (dollar/kWh)
-    unsigned char       Currency;                   // dispenser currency index
 };
 
 struct WARNING_CODE_INFO
@@ -815,16 +818,11 @@ typedef union
     struct
     {
         unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging                   ( dispenser -> cabinet)
-        unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStartConfirm:1;
-        unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStopConfirm:1;
-        unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop                                     (    ocpp   -> cabinet -> dispenser)
         unsigned int  UnlockStopConfirm:1;
         unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop                           ( dispenser -> cabinet)
         unsigned int  PsuReleasable:1;
-        unsigned int  AvailabilityRequest:1;            // 0: no request,    1: change availability                             (    ocpp   -> cabinet -> dispenser)
-        unsigned int  AccountBalanceRequest:1;          // 0: no request,    1: set account balance                             (    ocpp   -> cabinet -> dispenser)
         unsigned int  AnnounceBalance:1;                //
         unsigned int  StartWaitPlug:1;                  //
         unsigned int  NeedCleanAuthorizeInfo:1;         //
@@ -837,7 +835,7 @@ typedef union
         unsigned int  Disconnection:1;
         unsigned int  GfdDetection:1;                   // 0: stop,         1: start
         unsigned int  GetStartChargingSoc:1;            // 0: no effect,    1: get start soc
-        unsigned int  res:8;
+        unsigned int  res:13;
     }bits;
 }ConnectorParameter;
 
@@ -874,9 +872,12 @@ struct ConnectorInfoData
     float                   CapabilityCurrent;              // unit 0.1A
     float                   CapabilityPower;                // unit 0.1kW
 
-    unsigned int            UserPrice;                      // connector user's user price, unit: 0.01 (dollar / kWh)
-    unsigned int            TotalCost;                      // connector user's total cost, unit: 0.01 dollar
-    int                     AccountBalance;                 // connector user's account balance, unit: 0.01 dollar
+    float                   UserPrice;                      // connector user's user price, unit: 1 (dollar / kWh)
+    float                   TotalCost;                      // connector user's total cost, unit: 1 dollar
+    float                   AccountBalance;                 // connector user's account balance, unit: 1 dollar
+    float                   CostDiscount;                   // connector user's Discount or couponPoint, unit: 1 point
+    float                   EnergyCost;                     // connector user's energy cost, unit: 1 dollar
+    float                   ParkingFee;                     // connector user's parking fee, unit: 1 dollar
 };
 
 typedef union
@@ -892,23 +893,6 @@ typedef union
     }bits;
 }CabinetSettingFlag;
 
-typedef struct
-{
-    unsigned int ConnectionTimeout;             // unit: 1s
-    unsigned int DefaultPrice;                  // unit: 0.01dollar
-    unsigned int Currency;                      // currency index
-    unsigned int BackendStatus;                 // 0: disable, 1: connected, 2: disconnected
-    unsigned int EthernetStatus;                // 0: disable, 1: connected, 2: disconnected
-    unsigned int WiFiStatus;                    // 0: disable, 1: connected, 2: disconnected
-    unsigned int TelcomModemStatus;             // 0: disable, 1: connected, 2: disconnected
-    unsigned int BillingStatus;                 // 0: disable, 1: enable
-    unsigned int StopChargingButton;            // 0: disable, 1: enable
-    unsigned int HardwareReboot;                // 1: HardwareReboot, Other value: no effect
-    unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
-    unsigned int AuthModeConfig;                // 0: enable,  1: disable
-    unsigned int EVCCIDConfig;                  // 0: disable, 1: enable
-}CabinetMiscCommand;
-
 typedef struct DC_METER_INFO
 {
     double presetVoltage;                       // resolution: 1.000v
@@ -1011,11 +995,11 @@ struct SysInfoData
     unsigned char           AuthorizedType;             // record authorized type
     unsigned char           AuthorizedStatus;           // cabinet authorized status
     CabinetSettingFlag      CabinetSetting;
-    CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
     DC_Meter_Info DcMeterInfo[4];
     unsigned char           OTPTemp;                    // OTP Temperature
     unsigned char           OTPTempR;                   // OTP Recovery Temperature
+    struct LCD_OVERRIDE     LcdOveride;                 // LCD override info (no use anymore)
 };
 
 struct SysConfigAndInfo
@@ -1334,9 +1318,9 @@ char AlarmStatusCode[160][6]=
     "012326",   // System task is lost
     "012327",   // DC input ovp
     "012328",   // DC input uvp
-    "012329",   // reserved
-    "012330",   // reserved
-    "012331",   // reserved
+    "012329",   // Psu Can Communication Fault
+    "012330",   // Psu Dc to Dc OTP
+    "012331",   // Psu Dc to Dc OVP
     "012332",   // reserved
     "012333",   // reserved
     "012334",   // reserved
@@ -1351,7 +1335,7 @@ char AlarmStatusCode[160][6]=
     "012343",   // reserved
     "012344",   // AC: Meter IC communication timeout
     "012345",   // AC: Pilot negative error
-    "012346",   // reserved
+    "012346",   // Psu Communication error with CSU
     "012347",   // reserved
     "012348",   // reserved
     "012349",   // reserved
@@ -1521,13 +1505,17 @@ struct AlarmCodeData
             unsigned char DcInputOVP:1;                             //bit 7
             //AlarmVal[16]
             unsigned char DcInputUVP:1;                             //bit 0
-            unsigned char :7;                                       //reserved bit 1 ~ bit 7
+            unsigned char PsuCanCommFault:1;                        //bit 1
+            unsigned char PsuDcDcOtp:1;                             //bit 2
+            unsigned char PsuDcDcOvp:1;                             //bit 3
+            unsigned char :4;                                       //reserved bit 4 ~ bit 7
             //AlarmVal[17]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
             //AlarmVal[18]
             unsigned char MeterIcCommTimeout:1;                     //bit 0
             unsigned char PilotNegativeError:1;                     //bit 1
-            unsigned char :6;                                       //reserved bit 2 ~ bit 7
+            unsigned char PsuComminicationErrWithCSU:1;             //bit 2
+            unsigned char :5;                                       //reserved bit 3 ~ bit 7
             //AlarmVal[19]
             unsigned char :8;                                       //reserved bit 0 ~ bit 7
 		}bits;
@@ -2312,6 +2300,7 @@ struct PsuData
 	unsigned char           GroupCount;
 	unsigned char           Work_Step;
 	struct PsuModuleVer     PsuVersion[MAX_PSU_QUANTITY];
+	unsigned char           PsuStopChargeFlag;
 };
 
 /************************************************************************************/
@@ -4429,7 +4418,7 @@ struct OCPP16ConfigurationTable
 struct StrcutSetUserPrice
 {
     unsigned char   idToken[21];
-    unsigned char   price[256];
+    unsigned char   price[1024];
 };
 
 struct ChargingPrice
@@ -4473,13 +4462,13 @@ struct StrcutRunningCost
     struct IdlePrice        idlePrice;              // (optional) Price components while not charging. Optional if no idle fee is charged.
     struct NextPeriod       nextPeriod;             // (optional) Pricing for next period
     struct Triggers         triggerMeterValue;      // (optional) Triggers to request a new meter value. Optional if no idle fee charged.
-    unsigned char           description[256];       // Compatible California pricing V1.0
+    unsigned char           description[1024];      // Compatible California pricing V1.0
 };
 
 struct StrcutFinalCost
 {
     int             txId;
-    unsigned char   description[256];
+    unsigned char   description[1024];
 };
 
 struct StructCost
@@ -4598,6 +4587,58 @@ struct StructSessionTarget
     unsigned short      targetDuration;     // Unit: Minutes    0 is unlimit
 };
 
+//===================================
+// YES custom protocol
+//===================================
+struct StructChargerInfo
+{
+    unsigned char station_name[64];
+};
+
+struct StructWeatherInfo
+{
+    int   weatherId;
+    float temperature;
+};
+
+struct StructCreditDeductResult
+{
+    int txId;
+    unsigned char creditNo[64];
+    unsigned char vemData[80];
+    unsigned char ROC[20];
+    unsigned char RRN[20];
+    unsigned char storeId[20];
+    unsigned char approvalNo[20];
+    double        amount;
+    unsigned char deductResult:1;
+    unsigned char isDonateInvoice:1;
+};
+
+struct StructReaderStatus
+{
+    int readerStatus;
+    unsigned char creditNo[64];
+    unsigned char ReportReaderStatusReq:1;
+};
+
+struct StructTcciCustomData
+{
+    struct StructChargerInfo ChargerInfo;
+    struct StructWeatherInfo WeatherInfo;
+    struct StructCreditDeductResult DeductInfo;
+    struct StructReaderStatus ReaderStatus[CONNECTOR_QUANTITY];
+    unsigned char TriggerReaderReq[3];
+    unsigned char SerialNo[CONNECTOR_QUANTITY][37];
+    unsigned char VEMData[CONNECTOR_QUANTITY][65];
+
+    unsigned char ReportCreditDeductReq:1;
+    unsigned char ChargerInfoReq:1;
+    unsigned char ChargerInfoConf:1;
+    unsigned char WeatherInfoReq:1;
+    unsigned char WeatherInfoConf:1;
+};
+
 struct OCPP16Data
 {
     unsigned char                           OcppServerURL[512];     //http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
@@ -4787,6 +4828,7 @@ struct OCPP16Data
     struct StructSignCertificate                    SignCertificate;
     struct StructSignedFirmwareStatusNotification   SignedFirmwareStatusNotification;
     struct StructSessionTarget                      SessionTarget[CONNECTOR_QUANTITY];
+    struct StructTcciCustomData                     TcciCustomData;
 };
 
 
@@ -4831,6 +4873,7 @@ enum OCPP20CtrlrVariable
 	ChargingStation_SupplyPhases,
 	ChargingStation_SystemUptimeSec,
 	ChargingStation_FreeVend,
+	ChargingStation_FreeVendIdtag,
 	Connector_Available,
 	Connector_ConnectorType,
 	Connector_SupplyPhases,
@@ -4879,6 +4922,8 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_WebSocketPingInterval,
 	OCPPCommCtrlr_ResetRetries,
 	OCPPCommCtrlr_PublicKeyWithSignedMeterValue,
+    OCPPCommCtrlr_StatusNotificationPeriodically,
+    OCPPCommCtrlr_StatusNotificationInterval,
     OCPPCommCtrlr_VariableVersion,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
@@ -5099,7 +5144,7 @@ struct ChargingScheduleType
 
 struct ChargingProfileType
 {
-	unsigned short int id;											// Required. Id of ChargingProfile.
+	int id;											                // Required. Id of ChargingProfile.
 	unsigned short int stackLevel;									// Required. Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
 	unsigned char chargingProfilePurpose[36];						// Required. Defines the purpose of the schedule transferred by this profile
 	unsigned char chargingProfileKind[16];							// Required. Indicates the kind of schedule.

+ 1 - 15
EVSE/Projects/DD360ComBox/Apps/Makefile

@@ -113,12 +113,6 @@ CHKSYSTASK_SRC_FILES = $(patsubst %.o, %.c, $(CHKSYSTASK_OBJ_FILES))
 %.o: %.c
 	$(CC) $(CFLAGS) -c $<
 
-#Simulation
-SIMULATION_OBJ_FILES = $(COMMON_OBJ_FILES) simulation.o
-SIMULATION_SRC_FILES = $(patsubst %.o, %.c, $(SIMULATION_OBJ_FILES))
-%.o: %.c
-	$(CC) $(CFLAGS) -c $<
-
 #Event Log
 EVENTLOG_OBJ_FILES = $(COMMON_OBJ_FILES) $(DataBaseLib)/DataBase.o \
 						$(EventLogLib)/Module_EventLogging.o
@@ -148,7 +142,7 @@ all: CopyFile apps
 apps: MainTask DoCommTask EvCommTask UpdateFWTask ChkSysTask \
 		EventLoggingTask InternalCommTask LcmControlTask \
 			PrimaryCommTask ReadCmdlineTask UnsafetyOutputTool \
-				SimulationApp FactoryConfigApp OtherTools CleanExec
+				FactoryConfigApp OtherTools CleanExec
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
@@ -180,11 +174,6 @@ ChkSysTask:
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o Module_ChkSysTask.o $(ChkSysTaskLib)/Module_ChkSysTask.c
 	#$(CC) -o Module_ChkSysTask Module_ChkSysTask.o 
 
-SimulationApp:
-	$(CC) $(DEFINE) $(SIMULATION_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) -o simulation 
-	#$(CC) $(DEFINE) $(CFLAGS) -c -o simulation.o simulation.c
-	#$(CC) -o simulation simulation.o
-
 EventLoggingTask:
 	$(CC) $(DEFINE) $(EVENTLOG_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(Lib_SQLite3) -o Module_EventLogging
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o define.o $(DefineLib)/define.c
@@ -242,7 +231,6 @@ OtherTools:
 	cp -f Module_EvComm $(RootPath)
 	cp -f Module_UpdateFW $(RootPath)
 	cp -f Module_ChkSysTask $(RootPath)
-	cp -f simulation $(RootPath)
 	cp -f Module_EventLogging $(RootPath)
 	cp -f Module_InternalComm $(RootPath)
 	cp -f Module_LcmControl $(RootPath)
@@ -262,7 +250,6 @@ OtherTools:
 	cp -f Module_EvComm $(OutputPath)
 	cp -f Module_UpdateFW $(OutputPath)
 	cp -f Module_ChkSysTask $(OutputPath)
-	cp -f simulation $(OutputPath)
 	cp -f Module_EventLogging $(OutputPath)
 	cp -f Module_InternalComm $(OutputPath)
 	cp -f Module_LcmControl $(OutputPath)
@@ -282,7 +269,6 @@ CleanExec:
 	rm Module_EvComm
 	rm Module_UpdateFW
 	rm Module_ChkSysTask
-	rm simulation 
 	rm Module_EventLogging
 	rm Module_InternalComm
 	rm Module_LcmControl

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 804 - 60
EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.c


+ 120 - 3
EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.h

@@ -16,7 +16,7 @@
 #define TFTP_PULL_CMD                           "tftp"
 #define SIGTERM_MSG                             "SegmentFault.~~~~\n"
 
-#define MAX_REGISTER_NUM                        30
+#define MAX_REGISTER_NUM                        50
 
 #define CHECK_NETWORK_FAIL_COUNT                10//10
 #define CONNECT_SERVER_FAIL_COUNT               3//5
@@ -80,6 +80,25 @@
 #define REG_QRCODE_URL_INFO                     0X10
 #define REG_WAIT_PLUG_IT_STATE                  0x11
 #define REG_Ground_Fault_Detection              0x12
+#define REG_CABINET_DCM_VERSION                 0x13
+#define REG_CABINET_OTHER_VERSION               0x14
+#define REG_TOTAL_PSU_QUANTITY                  0x15
+#define REG_PSU_VERSION                         0x16
+#define REG_RESERVATION_IDTAG                   0x17
+#define REG_DISPENSER_REQUEST                   0x18
+#define REG_REMOTE_START_NO_ID                  0x19
+#define REG_REFUND_AMOUNT                       0x1A
+#define REG_PREPAYMENT_INFO                     0x1B
+#define REG_PAYMENT_FAIL_REASON                 0x1C
+#define REG_CONNECTOR_QR_CODE                   0x1D
+#define REG_STATION_INFO                        0x1E
+#define REG_DEDUCT_INFO                         0x1F
+#define REG_READ_CABINET_SYSTEMID               0x20
+#define REG_READ_DEFAULT_PRICE                  0x21
+#define REG_READ_USER_PRICE                     0x22
+#define REG_RECEIPT_INFO                        0x23
+#define REG_POWER_CONSUMPTION_INFO              0x24
+#define REG_READ_CHARGING_TIMESTAMP             0x25
 
 //------------------------------------------------------------------------------
 //--- dispenser result ---
@@ -111,19 +130,90 @@
 #define MISC_CMD_WEB_STOP_CHARGING              (0x000B)
 #define MISC_CMD_AUTH_DISABLE					(0x000C)
 #define MISC_CMD_EVCCID_ENABLE					(0x000D)
+#define MISC_CMD_LED_INTENSITY                  (0x000E)
+#define MISC_CMD_AC_CONTACTOR                   (0x000F)
+#define MISC_CMD_TIME_OFFSET                    (0x0010)
 
 #define MISC_CMD_HARDWARE_REBOOT                (0x0101)
 #define MISC_CMD_SOFTWARE_RESTART               (0x0102)
 #define MISC_CMD_REMOTE_START_CHARGING          (0x0103)
 #define MISC_CMD_REMOTE_STOP_CHARGING           (0x0104)
 #define MISC_CMD_REMOTE_UNLOCK                  (0x0105)
+#define MISC_CMD_RESERVATION                    (0x0106)
+#define MISC_CMD_CHANGE_LCM_PAGE                (0x0107)
+#define MISC_CMD_QR_CODE_REQ                    (0x0108)
+#define MISC_CMD_STATION_INFO_REQ               (0x0109)
+#define MISC_CMD_FINAL_COST_REQ                 (0x010A)
+#define MISC_CMD_LINE_STATUS_REQ                (0x010B)
+#define MISC_CMD_DEFAULT_PRICE_REQ              (0x010C)
+#define MISC_CMD_USER_PRICE_REQ                 (0x010D)
+#define MISC_CMD_RECEIPT_REQ                    (0x010E)
 
 #define ST_UPDATE_FIRMWARE                      (0x01)
 #define ST_NO_UPDATE_FIRMWARE                   (0x02)
 
+#define LCM_PAGE_REMOTE_START_NO_ID             (0x0001)
+#define DISPENSER_REQ_CHARGING_CANCEL           (0x0001)
+
+#define UPLOAD_DEDUCT_DB						(0x5656)
+
+
 //------------------------------------------------------------------------------
 #pragma pack(push)
 #pragma pack(1)
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ChargingCancel : 1; // 0: no effect, 1: charging cancel request
+        unsigned int res : 31;
+    }bits;
+} ConnectorActReqVar;
+
+typedef struct StDeductInfoVar {
+    unsigned char DeductResult;                     // 0: Fail, 1: Pass
+    unsigned char IsDonateInvoice;                  // 0: Do not donate, 1: Donate
+    int TransactionId;								// transaction id
+    int Amount;                                     // unit = 0.01 dollar
+    char ApprovalNumber[12];						// approval number
+} DeductInfoVar;
+
+/*
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int JoinLine:1;                    // 0: no effect,                1: JoinLine page is trigger
+        unsigned int PaymentSwitch:1;               // 0: no effect,                1: PaymentSwitch page is trigger
+        unsigned int res:30;
+    }bits;
+} ChangePageReq;
+*/
+
+typedef union
+{
+    unsigned int Value;
+    struct
+    {
+        unsigned int ReservationReq:1;              // 0: no effect,                1: need to request Reservation
+        unsigned int RemoteStartNoID:1;             // 0: no effect,                1: need to request RemoteStartNoID
+        unsigned int StationInfoReq:1;              // 0: no effect,                1: need to request StationInfo
+        unsigned int FinalCostReq:1;                // 0: no effect,                1: need to request FinalCost
+        unsigned int DefaultPriceReq : 1;           // 0: no effect,                1: need to request Default price
+        unsigned int UserPriceReq : 1;              // 0: no effect,                1: need to request User price
+        unsigned int ReceiptReq : 1;                // 0: no effect,                1: need to request Receipt
+        unsigned int res:27;
+    }bits;
+} MoreInfoReq;
+
+typedef struct StStationVar {
+    int StationID;
+    char StationName[64];
+    int WeatherID;
+    float Temperature;
+} StationVar;
 
 typedef struct StConnectorState {
     uint8_t State;
@@ -131,7 +221,8 @@ typedef struct StConnectorState {
     uint8_t ConnectorTemp;
     uint8_t ChillerTemp;
     uint8_t PlugIn;
-    uint8_t Reserved[2];
+    uint32_t consumption;
+    uint8_t Reserved[1];
 } ConnectorState;
 
 typedef struct StConnectorIDTable {
@@ -232,9 +323,35 @@ typedef struct StAccountInfo {
     int UserPrices;
     int TotalCost;
     int Balance;
-    uint8_t Reserved[3];
+    int Discount;
+    int Transaction;
+    int EnergyCost;
+    int ParkingFee;
+    uint32_t RemainAmount;
+    uint8_t Reserved[1];
 } AccountInfo;
 
+typedef struct stCabinetDCMVersion {
+    uint8_t CabinetModelName[32];
+    uint8_t CabinetBoolLoaderVersion[32];
+    uint8_t CabinetKernelVersion[32];
+    uint8_t CabinetRFSystemVersion[32];
+    uint8_t CabinetPrimaryVersion[32];
+    uint8_t CabinetIPAddr[32];
+}PCDCMVer;
+
+typedef struct stCabinetOtherVersion {
+    uint8_t CabinetRelay0Version[32];
+    uint8_t CabinetRelay1Version[32];
+    uint8_t CabinetFanVersion[32];
+}PCOthVer;
+
+typedef struct stCabinetEachPsuVersion {
+	uint8_t n_PSU;
+	uint8_t DCVersion[32];
+	uint8_t FPCVersion[32];
+}PCnPsuVer;
+
 #pragma pack(pop)
 
 #endif /* _DO_COMM_H_ */

+ 14 - 2
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Ev_Comm.c

@@ -13,7 +13,7 @@
 
 #include "Ev_Comm.h"
 #include "Module_EvComm.h"
-
+#include "../Config.h"
 //------------------------------------------------------------------------------
 int PackageIdCmd(int cmd)
 {
@@ -22,14 +22,26 @@ int PackageIdCmd(int cmd)
 
 void SendCmdToEvboard(int cmd, uint8_t *data, uint8_t dataLen)
 {
+    DcCommonInfo* ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
     int fd = GetCanFd();
     struct can_frame frame;
-
+    int i;
+    int len = 0;
+    char _info[1024];
     frame.can_id = cmd;
     frame.can_dlc = dataLen;
     memcpy(frame.data, data, sizeof(frame.data));
 
     write(fd, &frame, sizeof(struct can_frame));
+
+    if (ShmDcCommonData->showCanPackage) {
+        len += sprintf(&_info[len], "CAN Dispenser => EV Tx:\t[0x%X] ", cmd);
+        for (i = 0; i < dataLen; i++) {
+            len += sprintf(&_info[len], "%X ", data[i]);
+        }
+        len += sprintf(&_info[len], "\n");
+        printf("%s",_info);
+    }
 }
 
 //------------------------------------------------------------------------------

+ 154 - 43
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -226,6 +226,54 @@ static void AddrAssignment(uint8_t *data)
     //}
 }
 
+void CheckEvConnect(int gunIndex)
+{
+    int isSameType = FALSE;
+    int isDisconnect = FALSE;
+    int gunType = _Type_CCS_2;
+    struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+    struct InfoCodeData* pInfoCode = (struct InfoCodeData*)GetShmInfoCodeData();
+    struct ChargingInfoData* pDcChargingInfo_0 = (struct ChargingInfoData*)GetDcChargingInfoData(0);
+    struct ChargingInfoData* pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(1);
+
+    if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) {
+        isSameType = TRUE;
+        isDisconnect = ShmDcCommonData->pGunInfo[0].EVLoseFlag | ShmDcCommonData->pGunInfo[1].EVLoseFlag;
+        gunType = pDcChargingInfo_0->Type;
+    } else {
+        isDisconnect = ShmDcCommonData->pGunInfo[gunIndex].EVLoseFlag;
+        gunType = pDcChargingInfo->Type;
+    }
+
+    //log_info("ShmDcCommonData->EVDisconnectFlag[%d]:%d", gunIndex, ShmDcCommonData->EVDisconnectFlag[gunIndex]);
+    if (isDisconnect) {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = YES;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = YES;
+            break;
+        }
+
+    } else {
+        switch (gunType) {
+        case _Type_Chademo:
+            pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO;
+            break;
+        case _Type_CCS_2:
+            pInfoCode->InfoEvents.bits.CcsEvCommFail = NO;
+            break;
+        case _Type_GB:
+            pInfoCode->InfoEvents.bits.GbEvCommFail = NO;
+            break;
+        }
+    }
+}
+
 void CANReceiver(int fd)
 {
     pid_t canRecPid;
@@ -255,7 +303,11 @@ void CANReceiver(int fd)
         uint8_t lastConnTemp[2] = {0, 0};
         struct can_frame frame;
         ChillerTemp chiilerTemp = {0};
+        time_t CCS_PlugoutTimer[2] = { 0 };
         struct ChargingInfoData *pDcChargingInfo = NULL;
+        int len = 0;
+        char _info[1024];
+        int i;
 
         pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
         pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -269,11 +321,33 @@ void CANReceiver(int fd)
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
 
-        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        ShmDcCommonData->pGunInfo[0].EVLoseTimer = time((time_t*)NULL);
+        ShmDcCommonData->pGunInfo[1].EVLoseTimer = time((time_t*)NULL);
 
+        //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        CCS_PlugoutTimer[0] = time((time_t*)NULL);
+        CCS_PlugoutTimer[1] = time((time_t*)NULL);
         while (isContinue) {
             memset(&frame, 0, sizeof(struct can_frame));
 
+            for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
+                pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
+                // 檢查是否有收到EV小板訊號
+                if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[_index].EVLoseTimer > 3) &&
+                    !ShmDcCommonData->pGunInfo[_index].EVLoseFlag &&
+                    pDcChargingInfo->SystemStatus != S_UPDATE && !ShmDcCommonData->debugflag) {
+
+                    ShmDcCommonData->pGunInfo[_index].EVLoseTimer = time((time_t*)NULL);
+                    ShmDcCommonData->pGunInfo[_index].EVLoseFlag = TRUE;
+
+                    system("/sbin/ip link set can0 down");
+                    sleep(1);
+                    system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
+                    system("/sbin/ip link set can0 up");
+                }
+                CheckEvConnect(_index);
+            }
+
             nbytes = read(fd, &frame, sizeof(struct can_frame));
             if (nbytes <= 0) {
                 usleep(10000);
@@ -293,6 +367,16 @@ void CANReceiver(int fd)
             intCmd = (int) (frame.can_id & CAN_EFF_MASK & 0xFFFFFF00);
 
             recvID = ((uint8_t) (frame.can_id & 0x000000FF)); // 0x01 or 0x02
+            
+            if (ShmDcCommonData->showCanPackage) {
+                len = 0;
+                len += sprintf(&_info[len], "CAN Dispenser <= EV Rx:\t[0x%X] ", frame.can_id);
+                for (i = 0; i < nbytes; i++) {
+                    len += sprintf(&_info[len], "%X ", frame.data[i]);
+                }
+                len += sprintf(&_info[len], "\n");
+                printf("%s", _info);
+            }
 
             for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {                    // 假設有找到回應的 Index
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
@@ -325,6 +409,9 @@ void CANReceiver(int fd)
                 usleep(10000);
                 continue;
             }
+            // Reset Connect Timer
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
+            ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun);
             gunTypeIndex = pDcChargingInfo->type_index;
@@ -341,13 +428,30 @@ void CANReceiver(int fd)
                             pSysInfo->CurGunSelected = targetGun;
 #endif                        
                     } else if (frame.data[0] == UNPLUG) {
-                        log_info("Conn %d, Unplug. ", targetGun);
+                        if (pDcChargingInfo->Type != _Type_CCS_2)
+                            log_info("Conn %d, Unplug. ", targetGun);
                         strcpy( (char *) pDcChargingInfo->EVCCID, "");
                     } else {
                         log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]);
                     }
+                    if(pDcChargingInfo->RemoteStartFlag == YES) {
+                        pSysInfo->CurGunSelected = targetGun;
+                    }
+                }
+                // CCS 小板確認拔除三秒
+                if (pDcChargingInfo->Type == _Type_CCS_2) {
+                    if (frame.data[0] == UNPLUG) {
+                        if ((time((time_t*)NULL) - CCS_PlugoutTimer[targetGun]) > 3) {
+                            if (pDcChargingInfo->ConnectorPlugIn != frame.data[0])
+                                log_info("CCS Conn %d, Unplug. ", targetGun);
+                        } else {
+                            frame.data[0] = PLUG;
+                        }
+                    } else {
+                        CCS_PlugoutTimer[targetGun] = time((time_t*)NULL);
+                        frame.data[0] = PLUG;
+                    }
                 }
-
                 pDcChargingInfo->ConnectorPlugIn = frame.data[0];
                 pDcChargingInfo->PilotVoltage = frame.data[1];
 
@@ -424,6 +528,7 @@ void CANReceiver(int fd)
 
                     if (frame.data[1] > pDcChargingInfo->EvBatterySoc) {
                         pDcChargingInfo->EvBatterySoc = frame.data[1];
+                        log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc);
                     }
                 }
                 //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove
@@ -446,8 +551,8 @@ void CANReceiver(int fd)
                 //printf("RemainChargingDuration = %d",  pDcChargingInfo->RemainChargingDuration);
 
                 if (pDcChargingInfo->Type == _Type_Chademo) {
-                    //if (ShmCHAdeMOData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d CHAdeMO board status = %d ", targetGun, ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus);
                         ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -456,8 +561,8 @@ void CANReceiver(int fd)
                     ShmCHAdeMOData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmCHAdeMOData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_GB) {
-                    //if (ShmGBTData->ev[gunTypeIndex].EvDetection != frame.data[0])
-                    {
+                    if (ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
+                        log_info("Gun%d GB Board status = %d ", targetGun, ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
 
@@ -466,7 +571,8 @@ void CANReceiver(int fd)
                     ShmGBTData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
                     ShmGBTData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
                 } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
+                    if (ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus != frame.data[0] && frame.data[0] != 0xFF) {
+                        log_info("Gun%d CCS board status = %d ", targetGun, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus);
                         ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
                     }
                 }
@@ -549,20 +655,23 @@ void CANReceiver(int fd)
 
                     pDcChargingInfo->ChillerTemp = maxChillerTemp;
                 }
+                if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
+                    maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
+                    //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
+                    //    printConnTemp = YES;
+                    //}
+                    maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
+                    if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
+                    {
+                        lastConnTemp[targetGun] = maxConnTemp;
+                        printConnTemp = YES;
+                    }
 
-                maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
-                //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
-                //    printConnTemp = YES;
-                //}
-                maxConnTemp = getAvageTemp(maxConnTemp,targetGun);
-                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
-                {
-                    lastConnTemp[targetGun] = maxConnTemp;
-                    printConnTemp = YES;
+                    pDcChargingInfo->ConnectorTemp = maxConnTemp;
+                } else {
+                    //log_info("Connector%d Tmep is zero:[%d,%d]", gunTypeIndex, ShmDcCommonData->ConnectorTemp[gunTypeIndex][0],
+                    //    ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]);
                 }
-
-                pDcChargingInfo->ConnectorTemp = maxConnTemp;
-
                 //紀錄槍頭和水冷機溫度, 在系統狀態變化或溫度大於150
                 if ((ShmDcCommonData->SystemModeChange[targetGun] == YES) ||
                         (printConnTemp == YES) ||
@@ -573,11 +682,13 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d",
+                    log_info("Conn %d max temp = %d, chiller = [%d %d], chiller2 = [%d %d]",
                              targetGun,
-                             maxConnTemp,
-                             chillerTemp[0],
-                             chillerTemp[1]);
+                             pDcChargingInfo->ConnectorTemp,
+                             chiilerTemp.Temp[0],
+                             chiilerTemp.Temp[1],
+                             chiilerTemp.Temp[2],
+                             chiilerTemp.Temp[3]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
@@ -645,25 +756,25 @@ void CANReceiver(int fd)
                 break;
             case ACK_EVCCID_REQ:
 
-                        if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
-                            pDcChargingInfo->Type == _Type_CCS_2)
-                        {
-                            {
-                                memset (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        0,
-                                        sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
-                                memcpy (
-                                        ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
-                                        frame.data, frame.can_dlc );
-                            }
-
-                            sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
-                                    frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
-
-                            pDcChargingInfo->EVCCID [17] = '\0';
-                            log_info( "************* Gun %d->EVCCID = %s ************* ", targetGun, pDcChargingInfo->EVCCID );
-                        }
+                if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
+                    pDcChargingInfo->Type == _Type_CCS_2)
+                {
+                    {
+                        memset (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                0,
+                                sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
+                        memcpy (
+                                ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
+                                frame.data, frame.can_dlc );
+                    }
+
+                    sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
+                            frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
+
+                    pDcChargingInfo->EVCCID [17] = '\0';
+                    log_info( "Gun %d->EVCCID = %s ", targetGun, pDcChargingInfo->EVCCID );
+                }
                 break;
             default:
                 log_info("EV board = %d, Ack none defined. intCmd = %d  ", targetGun, intCmd);

+ 5 - 2
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -1028,7 +1028,7 @@ int main(int argc, char *argv[])
                 //if (waitPsuVolwithRealyVol(gunIndex) == NO) {
                 //    continue;
                 //}
-
+                GetEvBatteryInfo(gunIndex, pDcChargingInfo->Evboard_id); //DS60-120 add
                 // 計算 Power
                 pDcChargingInfo->PresentChargingPower =
                     ((float)((pDcChargingInfo->PresentChargingVoltage) *
@@ -1040,7 +1040,7 @@ int main(int argc, char *argv[])
                     chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                 } else {
                     int passTime = pDcChargingInfo->PresentChargedDuration - chargingTime[gunIndex];
-
+                    
                     if (passTime > 0) {
                         float changingPow = (pDcChargingInfo->PresentChargingPower) * passTime / 3600;
                         if (pSysConfig->BillingData.isBilling) {
@@ -1048,9 +1048,12 @@ int main(int argc, char *argv[])
                         }
 
                         pDcChargingInfo->PresentChargedEnergy += changingPow;
+
+                        ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption += changingPow;
                         pDcChargingInfo->PowerConsumption += changingPow;
                         chargingTime[gunIndex] = pDcChargingInfo->PresentChargedDuration;
                     }
+                    
                 }
 
                 // 開始確認車端是否同意開始充電

+ 24 - 24
EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/FanBoard.c

@@ -20,6 +20,7 @@ static struct SysInfoData *pSysInfo = NULL;
 static struct AlarmCodeData *pAlarmCode = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
+static DcCommonInfo* ShmDcCommonData = NULL;
 
 static int Uart5Fd = 0;
 static struct timeval gFanBoardRunTimer;
@@ -149,8 +150,8 @@ static void GetFanSpeedByFunction(void)
 static void SetRtcData_Fan(void)
 {
     struct timeb csuTime;
-    struct tm *tmCSU;
-    Rtc rtc = {0};
+    struct tm* tmCSU;
+    Rtc rtc = { 0 };
 
     ftime(&csuTime);
     tmCSU = localtime(&csuTime.time);
@@ -186,30 +187,42 @@ static void SetRtcData_Fan(void)
 static void SetModelName_Fan(void)
 {
     if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
-        return;
-    } else
-        log_info("******** Set Model name FAIL = %s ************", pSysConfig->ModelName);
+        log_info("Set Model name PASS = %s ", pSysConfig->ModelName);
+    }
 }
 
 static void GetFwAndHwVersion_Fan(void)
 {
-    Ver ver = {0};
+    Ver ver = { 0 };
 
     if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // FanModuleData
-        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        strcpy((char*)ShmFanModuleData->version, ver.Version_FW);
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleFwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s1 = %s ", ver.Version_FW);
     }
 
     if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
         // SystemInfo
-        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        strcpy((char*)pSysInfo->FanModuleHwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s2 = %s ", ver.Version_HW);
     }
 }
 
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
 static void fanBoardPorcess(void)
 {
     if (ShmFanModuleData->SelfTest_Comp == NO) {
@@ -217,8 +230,8 @@ static void fanBoardPorcess(void)
     }
 
     if (ShmFanModuleData->SelfTest_Comp == YES ||
-            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
-            pSysInfo->FanModuleFwRev[0] != '\0') {
+        strlen((char*)pSysInfo->FanModuleFwRev) != 0 ||
+        pSysInfo->FanModuleFwRev[0] != '\0') {
         ShmFanModuleData->SelfTest_Comp = YES;
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
@@ -239,19 +252,6 @@ static void fanBoardPorcess(void)
     }
 }
 
-static void fanBoardSelfTest(void)
-{
-    if (ShmFanModuleData->SelfTest_Comp == YES) {
-        return;
-    }
-
-    GetFwAndHwVersion_Fan();
-    SetModelName_Fan();
-    SetRtcData_Fan();
-    sleep(1);
-    gettimeofday(&gFanBoardRunTimer, NULL);
-}
-
 void FanBoardTask(int uartFD)
 {
 #if defined NO_FAN_BOARD || defined DD360ComBox

+ 6 - 1
EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/LEDlight.c

@@ -127,9 +127,10 @@ static void SetLedColor(void)
                 led_color.Connect_2_Red = _colorBuf;
             }
         } else {
+
+            // 實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -158,6 +159,8 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+
             }
 
             // --------------------------------------------------------------------------
@@ -191,6 +194,8 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+
             }
 
         }

+ 56 - 14
EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/RelayBoard.c

@@ -25,7 +25,7 @@ static DcCommonInfo *ShmDcCommonData = NULL;
 static struct WARNING_CODE_INFO *pSysWarning = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct FanModuleData *ShmFanModuleData = NULL;
-
+static struct GBTData* ShmGBTData = NULL;
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
@@ -36,7 +36,8 @@ static uint16_t fanSpeedSmoothValue = 1000;
 static Led_Color cur_led_color = {COLOR_MIN_LV};
 static Led_Color led_color;
 static struct timeval _led_priority_time;
-
+int ReservationLed;
+time_t ReservationFlashTimer;
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
@@ -361,10 +362,17 @@ static void GetGfdAdc(void)
 void CheckOutputPowerOverCarReq(uint8_t index)
 {
     struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
-
+    ShmGBTData = (struct GBTData*)GetShmGBTData();
     float fireV = pDcChargingInfo->FireChargingVoltage;
     float carV = pDcChargingInfo->EvBatteryMaxVoltage * 10;
-
+    /*
+    log_info("PresentChargingVoltage:%f, FireChargingVoltage:%f ", pDcChargingInfo->PresentChargingVoltage * 10, pDcChargingInfo->FireChargingVoltage);
+    log_info("fireV:%f, carV:%f, _isOvpChkTimeFlag:%d", fireV, carV, _isOvpChkTimeFlag[index]);
+    log_info("EvBatterytargetVoltage:%f", pDcChargingInfo->EvBatterytargetVoltage);
+    if (pDcChargingInfo->Type == _Type_GB) {
+        log_info("GB EV Board Status:%d", ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
+    }
+    */
     if ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 1500 &&
             (pDcChargingInfo->Type == _Type_Chademo ||
              pDcChargingInfo->Type == _Type_CCS_2 ||
@@ -1398,16 +1406,16 @@ static void fanBoardPorcess(void)
 
         if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
             //GetPsuTempForFanSpeed();
-            GetFanSpeedByFunction();
+            //GetFanSpeedByFunction();
             GetFanSpeed();
             pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
             gettimeofday(&gFanBoardRunTimer, NULL);
-
+            /*
             ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
             ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-
+            */
             //log_info("set fan = %d ", ShmFanModuleData->SetFan1Speed);
             SetFanModuleSpeed();
         }
@@ -1488,11 +1496,9 @@ static void SetLedColor(void)
     } else {
         if (pSysInfo->IsAlternatvieConf) {
             if ((chargingData_1->SystemStatus == S_BOOTING ||
-                    chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    chargingData_1->SystemStatus == S_IDLE ) &&
                     (chargingData_2->SystemStatus == S_BOOTING ||
-                     chargingData_2->SystemStatus == S_IDLE ||
-                     chargingData_2->SystemStatus == S_RESERVATION)) {
+                     chargingData_2->SystemStatus == S_IDLE)) {
 #if defined DD360Audi
                 led_color.Connect_1_Green = _colorBuf;
                 led_color.Connect_1_Blue = _colorBuf;
@@ -1528,12 +1534,25 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
-            }
+            } else if (chargingData_1->SystemStatus == S_RESERVATION ||
+                chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
 
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
         } else {
+            //實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
                     chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_RESERVATION ||
                     chargingData_1->SystemStatus == S_MAINTAIN) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
@@ -1562,13 +1581,20 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
+            } else if (chargingData_1->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_1_Green = _colorBuf;
+                }
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
             }
 
 
             // --------------------------------------------------------------------------
             if (chargingData_2->SystemStatus == S_BOOTING ||
                     chargingData_2->SystemStatus == S_IDLE ||
-                    chargingData_2->SystemStatus == S_RESERVATION ||
                     chargingData_2->SystemStatus == S_MAINTAIN) {
                 if (chargingData_2->IsAvailable == NO) {
                     led_color.Connect_2_Green = COLOR_MIN_LV;
@@ -1596,6 +1622,14 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;
+            } else if (chargingData_2->SystemStatus == S_RESERVATION) {
+                if (ReservationLed) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                } else {
+                    led_color.Connect_2_Green = _colorBuf;
+                }
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
             }
 
         }
@@ -1663,6 +1697,14 @@ static void LEDBoardProcess(void)
         //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
         //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
         //}
+        if (time((time_t*)NULL) - ReservationFlashTimer >= 3) {
+            ReservationFlashTimer = time((time_t*)NULL);
+            if (ReservationLed)
+                ReservationLed = 0;
+            else
+                ReservationLed = 1;
+        }
+
         SetLedColor();
         gettimeofday(&_led_priority_time, NULL);
     }

+ 258 - 301
EVSE/Projects/DD360ComBox/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -31,229 +31,6 @@ static struct ChargingInfoData *pDcChargingInfo = NULL;
 static struct ChargingInfoData *pAcChargingInfo = NULL;
 static DcCommonInfo *ShmDcCommonData            = NULL;
 
-bool needReloadQr = true;
-bool _saftydetect = false;
-bool _isShow = false; //DS60-120 add
-uint8_t _showInformIndex = 0; //DS60-120 add
-
-int _port;
-//char* pPortName         = "/dev/ttyO2";
-char *pPortName           = "/dev/ttyS3";
-char *moduleName          = "DMT80480T070_09WT";
-uint8_t _totalCount;
-uint8_t acgunCount;
-//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
-
-uint8_t ac_ani_battery_level    = _BATTERY_LEVEL_FOR_MAP_LV5;
-uint8_t isDiffStatus            = false;
-uint8_t isChangeBattMap         = false;
-// 當前選擇的槍號
-#if defined DD360Audi
-short _currentPage              = _LCM_SELECT_GUN;
-short _oldPage                  = _LCM_SELECT_GUN;
-#else
-short _currentPage              = _LCM_NONE;
-short _oldPage                  = _LCM_NONE;
-#endif //defined DD360Audi
-uint8_t _gunIndex               = 0;
-bool _wifi_conn_status          = false;
-bool _battery_display_ani       = false;
-uint8_t _curPage_index          = 0;
-bool _page_reload               = false;
-
-// LCM - HW
-uint8_t _everyPageRollChange    = 0;
-short __logo                    = 0x0000;
-short __conn_status             = 0x0030;
-short __ethernet_status         = 0x0032;
-short __3G4G_status             = 0x0036;
-short __3G4G_status1            = 0x0037;
-short __3G4G_move_status        = 0x0038;
-short __wifi_status             = 0x003C;
-
-short __sel_gun_btn             = 0x0040;
-short __ret_home_btn            = 0x0042;
-short __stop_method_btn         = 0x0044;
-short __lcm_version             = 0x004A;
-short __qr_code                 = 0x0250;
-short __main_rfid               = 0x0052;
-short __main_qr                 = 0x0054;
-short __main_app                = 0x0056;
-
-short __plug_in_arrow           = 0x0060;
-
-short __conn_line               = 0x0066;
-
-short __gun_type_index          = 0x0070;
-short __cmp_gun_type_index      = 0x0080; ////For Audi
-short __batt_map_empty          = 0x0090; ////For Audi
-short __qr_code_pre             = 0x0280;
-
-short __side_top                = 0x0090;
-short __side_down               = 0x0092;
-short __side_mid                = 0x0094;
-
-short __conn_line_chag          = 0x0096;
-short __batt_map                = 0x0100;
-short __soc_value_charging      = 0x0102;
-short __remain_time_map         = 0x0106;
-short __power_map               = 0x0108;
-short __energy_map              = 0x010A;
-short __remain_time_tx          = 0x0110;
-
-short __trp_remain_time_map     = 0x0116;
-short __trp_power_map           = 0x0118;
-short __trp_energy_map          = 0x011A;
-
-short __output_eng_tx           = 0x0120;
-short __total_out_eng_tx        = 0x0130;
-short __conn_line_comp          = 0x0140;
-short __charging_fee_map        = 0x0146;
-short __charging_fee_tx         = 0x0150;
-
-short __money_by_rate           = 0x0200;
-short __money_rate              = 0x0220;
-short __money_rate_map          = 0x0230;
-
-//DS60-120 add
-short __csu_ver_string          = 0x0300;
-short __csu_ver_value           = 0x0310;
-short __fan_speed_string        = 0x0390;
-short __fan_speed_value         = 0x0400;
-
-short __dc1_ver_string          = 0x0320;
-short __dc1_ver_value           = 0x0330;
-short __dc2_ver_string          = 0x0340;
-short __dc2_ver_value           = 0x0350;
-short __eth0_ip_string          = 0x0360;
-short __eth0_ip_value           = 0x0370;
-short __sn_string               = 0x0410;
-short __sn_value                = 0x0420;
-
-//For Audi, for select gun
-short __left_gun_map            = 0x0260;
-short __right_gun_map           = 0x0262;
-short __add_chk_btn             = 0x0264;
-//short __station_id            = 0x0270;
-short __balance                 = 0x0270;
-short __remain_balance          = 0x0280;
-short __custStationIdL1         = 0x0450;
-//short __custStationIdL2       = 0x0470;
-short _emergency_map            = 0x011C;
-short __logo_cmp                = 0x014A;
-// ICON ID
-uint8_t _disappear              = 0;
-uint8_t _disconnect             = 1;
-uint8_t _connect                = 2;
-uint8_t _warning                = 3;
-uint8_t _arrow_dark             = 4;
-uint8_t _arrow_light            = 5;
-uint8_t _3G4G_disconnect        = 6;
-uint8_t __3G4G_connect          = 7;
-uint8_t _wifi_disconnect        = 8;
-uint8_t _wifi_connect           = 9;
-uint8_t _logo                   = 10;
-uint8_t _conn_map1              = 11;
-uint8_t _conn_map2              = 12;
-uint8_t _sel_gun_btn            = 13;
-uint8_t _back_home_btn          = 14;
-uint8_t _stop_charging_btn      = 15;
-uint8_t _stop_charging_btn_scan = 16;
-uint8_t _chademo_dark           = 17;
-uint8_t _ccs_dark               = 18;
-uint8_t _gbt_dark               = 19;
-uint8_t _actype_dark            = 20;
-uint8_t _chademo_light          = 21;
-uint8_t _ccs_light              = 22;
-uint8_t _gbt_light              = 23;
-uint8_t _actype_light           = 24;
-uint8_t _main_none_rfid         = 25;
-uint8_t _main_rfid              = 26;
-uint8_t _main_none_app          = 27;
-uint8_t _main_app               = 28;
-uint8_t _main_none_qr           = 29;
-uint8_t _main_qr                = 30;
-uint8_t _charging_map1          = 31;
-uint8_t _charging_map2          = 32;
-uint8_t _battery_empty          = 33;
-uint8_t _battery_cap_20         = 34;
-uint8_t _battery_cap_40         = 35;
-uint8_t _battery_cap_60         = 36;
-uint8_t _battery_cap_80         = 37;
-uint8_t _battery_cap_100        = 38;
-uint8_t _battery_map            = 39;
-uint8_t _power_map              = 40;
-uint8_t _time_map               = 41;
-uint8_t _complete_map           = 42;
-uint8_t _battery_soc_20         = 43;
-uint8_t _battery_soc_40         = 44;
-uint8_t _battery_soc_60         = 45;
-uint8_t _battery_soc_80         = 46;
-uint8_t _battery_soc_100        = 47;
-uint8_t _battery_eng_map        = 48;
-uint8_t _money_map              = 49;
-uint8_t _elapse_time_map        = 50;
-uint8_t _charging_money         = 51;
-//uint8_t _side_none_rfid       = 52;
-//uint8_t _side_rfid            = 53;
-//uint8_t _side_none_app        = 54;
-//uint8_t _side_app             = 55;
-//uint8_t _side_none_qr         = 56;
-//uint8_t _side_qr              = 57;
-uint8_t _eth_disconnect         = 52; //58;
-uint8_t _eth_connect            = 53; //59;
-
-uint8_t _chademo_dark_cmp       = 54;
-uint8_t _ccs_dark_cmp           = 55;
-uint8_t _gbt_dark_cmp           = 56;
-uint8_t _actype_dark_cmp        = 57;
-uint8_t _chademo_light_cmp      = 58;
-uint8_t _ccs_light_cmp          = 59;
-uint8_t _gbt_light_cmp          = 60;
-uint8_t _actype_light_cmp       = 61;
-
-uint8_t _logo_cmp               = 62;
-uint8_t _battery_eng_trp_map    = 63;
-uint8_t _money_trp_map          = 64;
-uint8_t _elapse_time_trp_map    = 65;
-#if defined DD360Audi
-////For Audi
-uint8_t _left_gun_disable_map   = 66;
-uint8_t _left_gun_enable_map    = 67;
-uint8_t _right_gun_disable_map  = 68;
-uint8_t _right_gun_enable_map   = 69;
-uint8_t _select_gun_btn         = 70;
-uint8_t _emergency_disable_map  = 72;
-// For replug
-struct timespec showReplugStrTimer;
-struct timespec showFullTargetTimer;
-short __show_StatusString_value_1 = 0x0460;
-short __show_StatusString_value_2 = 0x0462;
-uint8_t _showfulltarget_1       = 73;
-uint8_t _showfulltarget_2       = 74;
-uint8_t _showReplugStr_1        = 75;
-uint8_t _showReplugStr_2        = 76;
-// Select Gun for Audi
-short __show_selectgun_value    = 0x0464;
-uint8_t _showselectgun_left     = 77;
-uint8_t _showselectgun_right    = 78;
-// Wait for gun plugin Audi
-short __show_waitgunplug_value    = 0x0468;
-uint8_t _showwaitgunplug_left     = 80;
-uint8_t _showwaitgunplug_right    = 81;
-#else
-short __show_handshark_value    = 0x0464;
-short __show_GFD_value          = 0x0466;
-short __show_precharge_value    = 0x0468;
-
-uint8_t _show_handshark_dark    = 67;
-uint8_t _show_handshark_light   = 68;
-uint8_t _show_GFD_dark          = 69;
-uint8_t _show_GFD_light         = 70;
-uint8_t _show_precharge_dark    = 71;
-uint8_t _show_precharge_light   = 72;
-#endif
 //#define log_info(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_error(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -432,8 +209,8 @@ void ReadMsgFromLcm(uint8_t *msg, uint8_t readLen)
             {
                 if(strcmp((char *)pSysInfo->LcmHwRev, "") != EQUAL)
                     strcpy((char *)pSysInfo->LcmHwRev, moduleName);
-
-                ShmDcCommonData->LcmFwVersion = atoi((char *)(msg + 7));
+                if (atoi((char*)(msg + 7)) != 0)
+                    ShmDcCommonData->LcmFwVersion = atoi((char*)(msg + 7));
                 //printf("msg = %d \n", ShmDcCommonData->LcmFwVersion);
     //              printf("msg = %x \n", *(msg + 7));
     //              printf("msg = %x \n", *(msg + 8));
@@ -521,7 +298,25 @@ void DisplayValueToLcm(short address, uint8_t *data, uint8_t len)
 
     WriteCmdToLcm(cmd, cmd[2] + 3);
 }
+void DisplayFeeValueToLcm(short address, uint8_t* data, uint8_t len)
+{
+    uint8_t cmd[256];
+    memset(cmd, 0x00, sizeof(cmd));
 
+    cmd[0] = CMD_TITLE_1;
+    cmd[1] = CMD_TITLE_2;
+    cmd[2] = 0x03 + len;
+    cmd[3] = CMD_MULTI_WRITE;
+    cmd[4] = address >> 8;
+    cmd[5] = address & 0x00FF;
+
+    for (uint8_t count = 0; count < len; count++)
+    {
+        cmd[12 + count] = *(data + count);
+    }
+
+    WriteCmdToLcm(cmd, cmd[2] + 3);
+}
 void ChangeDisplay2Value(short address, short value)
 {
     uint8_t data[2];
@@ -579,7 +374,7 @@ void ChangeWarningFunc()
     //log_info("WarningCount = %d ", pSysWarning->WarningCount);
 //#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
     for (i = 0; (i + pSysWarning->PageIndex * 5) < pSysWarning->WarningCount; i++) {
-        log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
+        //log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
         memset(cmd, 0x00, sizeof(cmd));
         if ((i) >= 5) {
             break;
@@ -840,6 +635,7 @@ uint8_t demoCount = 0;
 void DemoFunction()
 {
     if (demoCount == 0) {
+        /*
         pSysWarning->WarningCount = 6;
         memcpy(&pSysWarning->WarningCode[0][0], "000001", 7);
         memcpy(&pSysWarning->WarningCode[1][0], "000002", 7);
@@ -847,24 +643,38 @@ void DemoFunction()
         memcpy(&pSysWarning->WarningCode[3][0], "000004", 7);
         memcpy(&pSysWarning->WarningCode[4][0], "000005", 7);
         memcpy(&pSysWarning->WarningCode[5][0], "000006", 7);
+        */
     } else {
         if (demoCount == 20) {
             pSysInfo->PageIndex = _LCM_IDLE;
-        } else if (demoCount == 80) {
+            /*
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_AUTHORIZING;
-        } else if (demoCount == 100) {
+        } else if (demoCount == 80) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_COMP;
-        } else if (demoCount == 120) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_AUTHORIZ_FAIL;
-        } else if (demoCount == 140) {
+            */
+        } else if (demoCount == 60) {
             pSysInfo->PageIndex = _LCM_PRE_CHARGE;
-        } else if (demoCount == 180) {
+        } else if (demoCount == 100) {
             pSysInfo->PageIndex = _LCM_CHARGING;
+        } else if (demoCount == 160) {
+            pSysInfo->PageIndex = _LCM_COMPLETE;
         }
     }
+    pSysInfo->CurGunSelected = LEFT_GUN_NUM;
+    sprintf((char*)ShmDcCommonData->QRCodeString, "%s", pSysConfig->SystemId);
 
-    if (demoCount < 180) {
+    sprintf((char*)ShmDcCommonData->pGunInfo[LEFT_GUN_NUM].ReceiptInfo, "%s", pSysConfig->SystemId);
+    pSysConfig->BillingData.isBilling = 1;
+    sprintf((char*)ShmDcCommonData->DefaultPriceString, "AM10:~10:00:$ 2, AM10:00~PM05:00:$ 3, PM05:00~AM00:00:$ 2");
+
+
+    if (demoCount <= 200) {
         demoCount++;
+    } else {
+        demoCount = 0;
     }
 }
 
@@ -1117,6 +927,7 @@ void ChangeRemainTime(int sec)
     s = (sec - (3600 * h) - (m * 60));
     sprintf((char *)value, "%02d:%02d:%02d", h, m, s);
     string2ByteArray(value, cmd);
+
     DisplayValueToLcm(__remain_time_tx, cmd, sizeof(cmd));
 }
 
@@ -1126,12 +937,10 @@ void ChangeChargingEnergyValue(float energy)
     uint8_t value[10];
 
     memset(cmd, 0x00, sizeof(cmd));
-    if (energy >= 0.05) {
-        energy -= 0.05;
-    }
-    sprintf((char *) value, "%.1f kWh", energy);
+
+    sprintf((char*)value, "%.4f kWh", energy);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__total_out_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_energy, cmd, sizeof(cmd));
 }
 
 void ChangeChargingPowerValue(float pow)
@@ -1146,7 +955,7 @@ void ChangeChargingPowerValue(float pow)
 //  pow = (max - min) * rand() / (RAND_MAX + 1.0) + min;
     sprintf((char *) value, "%.1f kW", pow);
     string2ByteArray(value, cmd);
-    DisplayValueToLcm(__output_eng_tx, cmd, sizeof(cmd));
+    DisplayValueToLcm(__present_power, cmd, sizeof(cmd));
 }
 
 void ChangeChargingFeeValue(float fee)
@@ -1161,6 +970,62 @@ void ChangeChargingFeeValue(float fee)
     DisplayValueToLcm(__charging_fee_tx, cmd, sizeof(cmd));
 }
 
+void ChangeEnergyCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+    if (fee >= 0 )
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_EnergyCost, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_EnergyCost, cmd, sizeof(cmd));
+}
+void ChangeParkingFeeValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+    string2ByteArray(value, cmd);
+
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_ParkingFee, cmd, sizeof(cmd));
+    else if (page == _LCM_PRE_CHARGE)
+        DisplayValueToLcm(__Prepare_ParkingFee, cmd, sizeof(cmd));
+}
+void ChangeTotalCostValue(float fee,int page)
+{
+    uint8_t cmd[10];
+    uint8_t value[10];
+
+    memset(cmd, 0x00, sizeof(cmd));
+
+    if (fee >= 0)
+        sprintf((char*)value, "$ %.2f", fee);
+    else
+        sprintf((char*)value, "--");
+
+    string2ByteArray(value, cmd);
+    if (page == _LCM_CHARGING)
+        DisplayValueToLcm(__Charge_TotalCost, cmd, sizeof(cmd));
+    else if (page == _LCM_COMPLETE)
+        DisplayValueToLcm(__Complete_TotalCost, cmd, sizeof(cmd));
+}
 void DisplayMoneyRate(float money)
 {
     uint8_t cmd[8];
@@ -1186,6 +1051,13 @@ void DisplayMoneyCur(uint8_t *cur)
     string2ByteArray(buf, cmd);
     DisplayValueToLcm(__money_rate, cmd, sizeof(cmd));
 }
+void DisplayReceipt(char* pString)
+{
+    char data[200];
+    memset(data, '\0', sizeof(data));
+    strcpy(data, pString);
+    DisplayValueToLcm(__Receipt_value, data, 200);
+}
 
 void RefreshPageAnimation(uint8_t value)
 {
@@ -1579,6 +1451,29 @@ void DisplayInfoEthIp(bool isShow, uint8_t *ip)
     }
 }
 
+void DisplayInfoConsumption(bool isShow)
+{
+    float data = 0;
+    if (isShow) {
+        uint8_t value[20];
+
+        memset(value, 0x00, sizeof(value));
+        strcpy((char*)value, "PWCT >");
+        DisplayValueToLcm(__eth0_ip_string, value, sizeof(value));
+        memset(value, 0x00, sizeof(value));
+        data = ShmDcCommonData->pConsumption.Gun1_Consumption +
+            ShmDcCommonData->pConsumption.Gun2_Consumption +
+            ShmDcCommonData->pConsumption.Gun3_Consumption +
+            ShmDcCommonData->pConsumption.Gun4_Consumption;
+
+        sprintf((char*)value,"%.4f",data);
+
+        DisplayValueToLcm(__eth0_ip_value, value, sizeof(value));
+    } else {
+        ChangeDisplay2Value(__eth0_ip_string, _disappear);
+        ChangeDisplay2Value(__eth0_ip_value, _disappear);
+    }
+}
 void Show4GRssi(bool isShow, int dbValue)
 {
     if (isShow) {
@@ -1745,8 +1640,7 @@ void InformationShow()
             DisplayInfoCsuVer(show, pSysInfo->CsuRootFsFwRev);
             DisplayInfoSpeed(show, pSysInfo->SystemFanRotaSpeed);
             DisplayInfoSN(show, pSysConfig->SerialNumber);
-
-            DisplayInfoEthIp(show, pSysConfig->Eth0Interface.EthIpAddress);
+            DisplayInfoConsumption(show);
             DisplayInfoGun1Ver(show, pSysInfo->Connector1FwRev);
             if (_totalCount > 1) {
                 DisplayInfoGun2Ver(show, pSysInfo->Connector2FwRev);
@@ -1808,14 +1702,58 @@ void ChangeTimeValue(uint8_t time)
     string2ByteArray(value, cmd);
     DisplayValueToLcm(0x1290, cmd, sizeof(cmd));
 }
+void ShowDateTime()
+{
+    struct timeb SeqEndTime;
+    struct tm* tm;
+    char _date[20];
+    char _time[20];
+    char _am_pm[10];
+
+    ftime(&SeqEndTime);
+    SeqEndTime.time = time(NULL);
+    
+    tm = localtime(&SeqEndTime.time);
+
+    sprintf(_date, "%04d/%02d/%02d",
+        tm->tm_year + 1900,
+        tm->tm_mon + 1,
+        tm->tm_mday);
 
+    if (tm->tm_hour >= 12) {
+        sprintf(_am_pm,"p.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour-12,
+            tm->tm_min);
+    } else {
+        sprintf(_am_pm, "a.m.");
+        sprintf(_time, "%02d:%02d",
+            tm->tm_hour,
+            tm->tm_min);
+    }
+    DisplayValueToLcm(__date_map, _date, strlen(_date)+1);
+    DisplayValueToLcm(__time_map, _time, strlen(_time)+1);
+    DisplayValueToLcm(__time_am_pm, _am_pm, strlen(_am_pm)+1);
+}
+uint8_t old_string[255];
+void ShowAnimationPrice(char* pString)
+{
+    uint8_t cmd[230];
+    memset(cmd, 0x00, sizeof(cmd));
+    string2ByteArray((uint8_t*)pString,cmd);
+    int len = strlen(pString);
+
+    if (strcmp((char*)old_string, pString) != EQUAL) {
+        strcpy((char*)old_string, pString);
+        DisplayFeeValueToLcm(__Animation_Price, cmd, sizeof(cmd));
+    }
+}
 void ProcessPageInfo()
 {
     _page_reload = IsPageReloadChk();
     pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
     struct InfoCodeData *pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData();
     struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
-    uint8_t i;
 
     // 隨插即充 - 可省略該按鈕 //DS60-120 add
     if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) {
@@ -1827,6 +1765,9 @@ void ProcessPageInfo()
         }
     }
     showPhihongLogo(false);
+    // Show Time
+    ShowDateTime();
+
     switch (_currentPage) {
 #if defined DD360Audi
     case _LCM_SELECT_GUN: ////For Audi
@@ -1842,7 +1783,7 @@ void ProcessPageInfo()
 #endif //defined DD360Audi
 
     case _LCM_IDLE: {
-
+        ChangeDisplayMoneyInfo();
         if (pSysConfig->isRFID) {
             ChangeDisplay2Value(__main_rfid, _main_rfid);
         } else {
@@ -1871,6 +1812,8 @@ void ProcessPageInfo()
         //if (FirstPageChanged() == YES || needReloadQr || _page_reload) {
         if (pSysConfig->isQRCode) {
             needReloadQr = false;
+            ChangeQrCode_Idle((char*)ShmDcCommonData->QRCodeString);
+            /*
             if (pSysConfig->QRCodeMadeMode == NO) {
                 //uint8_t len = strlen((char *)pSysConfig->SystemId);
                 ChangeQrCode_Idle((char *)pSysConfig->SystemId);
@@ -1879,6 +1822,7 @@ void ProcessPageInfo()
                 ChangeQrCode_Idle((char *)pSysConfig->QRCodeContent);
             }
             //ChangeQrCode_Idle((char *)pSysConfig->SystemId);
+            */
         }
         //}
 
@@ -1979,7 +1923,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2008,7 +1952,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pAcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pAcChargingInfo->PresentChargedEnergy > 0 &&
                             pAcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pAcChargingInfo->PresentChargedEnergy);
 
@@ -2047,6 +1991,8 @@ void ProcessPageInfo()
             }
         }
 
+        ChangeDisplay2Value(__money_by_rate, _disappear);
+
         gunTargetIndex = 0; //DS60-120 add
         for (uint8_t i = 0; i < _totalCount; i++) {
             if (_totalCount == 1 && acgunCount <= 0) { //DS60-120 add
@@ -2111,53 +2057,16 @@ void ProcessPageInfo()
             if (_currentPage == _LCM_PRE_CHARGE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
                     ChangeBattMapAndValue(_currentPage, pDcChargingInfo->EvBatterySoc);
-                    uint8_t precharg_time = (GetPreChargeTimeoutValue(pDcChargingInfo->PreChargeTimer)/1) / uSEC_VAL;
-                    if (precharg_time > PRECHARGING_TTIMEOUT)
-                        precharg_time = PRECHARGING_TTIMEOUT;
-                    ChangeTimeValue(PRECHARGING_TTIMEOUT- precharg_time);
-
-                    if (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                            pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EV) {
-                        pDcChargingInfo->_SaftyDetect = false;
-                        ChangeDisplay2Value(__show_handshark_value, _show_handshark_light);
-                        ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                        ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-
-                    } else if (pDcChargingInfo->SystemStatus == S_PREPARING_FOR_EVSE) {
-                        if (pDcChargingInfo->Type == _Type_Chademo || pDcChargingInfo->Type == _Type_GB) {
-                            if (pDcChargingInfo->_SaftyDetect == false ) {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                                if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                    pDcChargingInfo->_SaftyDetect = true;
-                            } else {
-                                ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                                ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                                ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                            }
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                        }
-                    } else if (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0 ||
-                            pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1) {
-                        if (pDcChargingInfo->_SaftyDetect == false ) {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_light);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_dark);
-                            if (pDcChargingInfo->EvBatterytargetVoltage == 0)
-                                pDcChargingInfo->_SaftyDetect = true;
-                        } else {
-                            ChangeDisplay2Value(__show_handshark_value, _show_handshark_dark);
-                            ChangeDisplay2Value(__show_GFD_value, _show_GFD_dark);
-                            ChangeDisplay2Value(__show_precharge_value, _show_precharge_light);
-                        }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
                     } else {
-                        ChangeDisplay2Value(__show_handshark_value, _disappear);
-                        ChangeDisplay2Value(__show_GFD_value, _disappear);
-                        ChangeDisplay2Value(__show_precharge_value, _disappear);
+                        ShowAnimationPrice("");
                     }
                 }
             } else if (_currentPage == _LCM_CHARGING && !isShowAc) {
@@ -2177,7 +2086,7 @@ void ProcessPageInfo()
                         ChangeChargingPowerValue(0);
                     }
 
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
                     } else {
@@ -2190,6 +2099,21 @@ void ProcessPageInfo()
                     } else {
                         ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                        ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee > 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+
+                    if (pSysConfig->BillingData.isBilling) {
+                        ShowAnimationPrice(ShmDcCommonData->pGunInfo[i].UserPriceString);
+                    } else {
+                        ShowAnimationPrice("");
+                    }
                 }
             } else if (_currentPage == _LCM_COMPLETE && !isShowAc) {
                 if (pSysInfo->CurGunSelected == i) {
@@ -2207,8 +2131,9 @@ void ProcessPageInfo()
                     } else {
                         ChangeChargingPowerValue(0);
                     }
+
 #if 1
-                    if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
+                    if (pDcChargingInfo->PresentChargedEnergy > 0 &&
                             pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                         ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2224,6 +2149,23 @@ void ProcessPageInfo()
                             ChangeBalanceValue(__remain_balance, i);
                         }
                     }
+                    /////////////////////// CTEP Add ///////////////////////
+                    if (strlen((char*)ShmDcCommonData->pGunInfo[i].ReceiptInfo) > 0) {
+                        DisplayReceipt(ShmDcCommonData->pGunInfo[i].ReceiptInfo);
+                        ChangeDisplay2Value(__receipt_backgroud, _receipt_bk);
+                    } else {
+                        DisplayReceipt("");
+                        ChangeDisplay2Value(__receipt_backgroud, _disappear);
+                    }
+                    // EnergyCost
+                    ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
+                    // Parking Fee
+                    ChangeParkingFeeValue(ShmSelectGunInfo->PricesInfo[i].ParkingFee, _currentPage);
+                    // Total Cost
+                    if (pDcChargingInfo->ChargingFee >= 0) {
+                        ChangeTotalCostValue(pDcChargingInfo->ChargingFee, _currentPage);
+                    }
+                    
 #else
                     ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
 
@@ -2274,6 +2216,8 @@ void ProcessPageInfo()
                     if (pSysConfig->isQRCode) {
                         needReloadQr = false;
                         //ChangeQrCode_Charge((char *)pSysConfig->SystemId); //DS60-120 remove
+                        ChangeQrCode_Charge((char*)ShmDcCommonData->QRCodeString);
+                        /*
                         if (pSysConfig->QRCodeMadeMode == NO) {
                             //uint8_t len = strlen((char *)pSysConfig->SystemId);
                             ChangeQrCode_Charge((char *)pSysConfig->SystemId);
@@ -2281,6 +2225,7 @@ void ProcessPageInfo()
                             //uint8_t len = strlen((char *)pSysConfig->QRCodeContent);
                             ChangeQrCode_Charge((char *)pSysConfig->QRCodeContent);
                         }
+                        */
                     }
                 }
             }
@@ -2302,6 +2247,11 @@ void ProcessPageInfo()
             break;
             }
         }
+#else
+        if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == 1) {
+            ChangeToOtherPage(_LCM_EMERGENCY);
+            break;
+        }
 #endif
 
         break;
@@ -2325,10 +2275,11 @@ void ChangeDisplayMoneyInfo()
             DisplayMoneyRate(ShmSelectGunInfo->PricesInfo[curGun].UserPrices);
         } else {
 #endif //defined DD360Audi
-            if (tmCSU->tm_hour <= 23) {
-                pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
-                DisplayMoneyRate(pSysConfig->BillingData.Cur_fee);
-            }
+
+            pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
+            ChangeDisplay2Value(__money_by_rate, _disappear);
+            ShowAnimationPrice(ShmDcCommonData->DefaultPriceString);
+
 
             if (pSysConfig->BillingData.Currency <= 53) {
                 DisplayMoneyCur((uint8_t *)GetCurrency(pSysConfig->BillingData.Currency));
@@ -2340,6 +2291,7 @@ void ChangeDisplayMoneyInfo()
         ChangeDisplay2Value(__money_rate_map, _disappear);
         ChangeDisplay2Value(__money_by_rate, _disappear);
         ChangeDisplay2Value(__money_rate, _disappear);
+        ShowAnimationPrice("");
     }
 }
 
@@ -2390,6 +2342,7 @@ void DefaultIconStatus()
     for (uint8_t i = 0; i < 3; i++) {
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
+    ChangeDisplay2Value(__sel_gun_btn, _disappear);
 
     if (pSysInfo->IsAlternatvieConf == YES || _totalCount == 1) {
         ChangeDisplay2Value(__sel_gun_btn, _disappear);
@@ -2429,7 +2382,7 @@ int main(void)
     pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
-    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();;
+    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
     ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
     struct StatusCodeData *ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();;
@@ -2438,6 +2391,7 @@ int main(void)
     _port = CreateCommunicationLcmPort();
     uint8_t changeWarningPriority = 0;
     uint8_t curWarningCount = 255;
+    uint8_t changeInfoPriority = 0;
     ChangeBackLight(true);
     _totalCount = pSysConfig->TotalConnectorCount;
     acgunCount = pSysConfig->AcConnectorCount;
@@ -2450,7 +2404,7 @@ int main(void)
         ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
     }
 
-    uint8_t _verShowCount = 3;
+    uint8_t _verShowCount = 5;
     DefaultIconStatus(); //DS60-120 add
 
     while (_port != -1) {
@@ -2501,10 +2455,13 @@ int main(void)
 #if defined DD360Audi
             ChangeDisplayMoneyInfo();
 #else
-            if (changeWarningPriority == 0) { ////For Audi
-                ChangeDisplayMoneyInfo();
-                InformationShow();
+            InformationShow();
+            /*
+            if (changeInfoPriority == 0) { ////For Audi
+                //ChangeDisplayMoneyInfo();
+                
             }
+            */
 #endif //defined DD360Audi
 
             changeWarningPriority >= 15 ? (_battery_display_ani = true) : (_battery_display_ani = false);

+ 278 - 4
EVSE/Projects/DD360ComBox/Apps/ModuleLcmCtrl/Module_LcmControl.h

@@ -1,6 +1,35 @@
 #ifndef MODULE_LCM_CTRL_H_
 #define MODULE_LCM_CTRL_H_
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
 
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+#include    "../Define/define.h"
+#include    "../Config.h"
 //------------------------------------------------------------------------------
 #define DEFAULT_AC_INDEX                        (2)
 
@@ -17,10 +46,6 @@
 
 #define CMD_BACKLIGHT                           (0x01)
 #define CMD_REGISTER                            (0x03)
-
-//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
-#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
-
 //------------------------------------------------------------------------------
 enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_EMP = 0x00,
@@ -31,4 +56,253 @@ enum _BATTERY_LEVEL_FOR_MAP {
     _BATTERY_LEVEL_FOR_MAP_LV5 = 0x05,
 };
 
+
+//#define NOODOE_QR_CODE_URL                    "https://ev-alpha-test.noodoe.com/station?id=" ////For Audi
+#define NOODOE_QR_CODE_URL                      "https://ev.noodoe.com/station?id=" ////For Audi
+#define CTEP_VERSION 002
+bool needReloadQr = true;
+bool _saftydetect = false;
+bool _isShow = false; //DS60-120 add
+uint8_t _showInformIndex = 0; //DS60-120 add
+
+int _port;
+//char* pPortName         = "/dev/ttyO2";
+char* pPortName = "/dev/ttyS3";
+char* moduleName = "DMT80480T070_09WT";
+uint8_t _totalCount;
+uint8_t acgunCount;
+//struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+//struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
+
+uint8_t ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV5;
+uint8_t isDiffStatus = false;
+uint8_t isChangeBattMap = false;
+// 當前選擇的槍號
+#if defined DD360Audi
+short _currentPage = _LCM_SELECT_GUN;
+short _oldPage = _LCM_SELECT_GUN;
+#else
+short _currentPage = _LCM_NONE;
+short _oldPage = _LCM_NONE;
+#endif //defined DD360Audi
+uint8_t _gunIndex = 0;
+bool _wifi_conn_status = false;
+bool _battery_display_ani = false;
+uint8_t _curPage_index = 0;
+bool _page_reload = false;
+
+// LCM - HW
+uint8_t _everyPageRollChange = 0;
+short __logo = 0x0000;
+short __conn_status = 0x0030;
+short __ethernet_status = 0x0032;
+short __3G4G_status = 0x0036;
+short __3G4G_status1 = 0x0037;
+short __3G4G_move_status = 0x0038;
+short __wifi_status = 0x003C;
+
+short __sel_gun_btn = 0x0040;
+short __ret_home_btn = 0x0042;
+short __stop_method_btn = 0x0044;
+short __lcm_version = 0x004A;
+short __qr_code = 0x0250;
+short __main_rfid = 0x0052;
+short __main_qr = 0x0054;
+short __main_app = 0x0056;
+
+short __plug_in_arrow = 0x0060;
+
+short __conn_line = 0x0066;
+
+short __gun_type_index = 0x0070;
+short __cmp_gun_type_index = 0x0080; ////For Audi
+short __batt_map_empty = 0x0090; ////For Audi
+short __qr_code_pre = 0x0280;
+
+short __side_top = 0x0090;
+short __side_down = 0x0092;
+short __side_mid = 0x0094;
+
+short __conn_line_chag = 0x0096;
+short __batt_map = 0x0100;
+short __soc_value_charging = 0x0102;
+short __remain_time_map = 0x0106;
+short __power_map = 0x0108;
+short __energy_map = 0x010A;
+short __remain_time_tx = 0x0110;
+
+short __trp_remain_time_map = 0x0116;
+short __trp_power_map = 0x0118;
+short __trp_energy_map = 0x011A;
+
+short __output_eng_tx = 0x0120;
+short __total_out_eng_tx = 0x0130;
+short __conn_line_comp = 0x0140;
+short __charging_fee_map = 0x0146;
+short __charging_fee_tx = 0x0150;
+
+short __money_by_rate = 0x0200;
+short __money_rate = 0x0220;
+short __money_rate_map = 0x0230;
+
+//DS60-120 add
+short __csu_ver_string = 0x0300;
+short __csu_ver_value = 0x0310;
+short __fan_speed_string = 0x0390;
+short __fan_speed_value = 0x0400;
+
+short __dc1_ver_string = 0x0320;
+short __dc1_ver_value = 0x0330;
+short __dc2_ver_string = 0x0340;
+short __dc2_ver_value = 0x0350;
+short __eth0_ip_string = 0x0360;
+short __eth0_ip_value = 0x0370;
+short __sn_string = 0x0410;
+short __sn_value = 0x0420;
+
+//For Audi, for select gun
+short __left_gun_map = 0x0260;
+short __right_gun_map = 0x0262;
+short __add_chk_btn = 0x0264;
+//short __station_id            = 0x0270;
+short __balance = 0x0270;
+short __remain_balance = 0x0280;
+short __custStationIdL1 = 0x0450;
+//short __custStationIdL2       = 0x0470;
+short _emergency_map = 0x011C;
+short __logo_cmp = 0x014A;
+
+// CTEP
+short __remain_time = 0x0110;
+short __present_power = 0x0120;
+short __present_energy = 0x0130;
+short __date_map = 0x0470;
+short __time_map = 0x0480;
+short __time_am_pm = 0x0489;
+short __Prepare_EnergyCost = 0x0500;
+short __Prepare_ParkingFee = 0x0510;
+short __Charge_EnergyCost = 0x0610;
+short __Charge_ParkingFee = 0x0620;
+short __Charge_TotalCost = 0x0630;
+short __Complete_EnergyCost = 0x0640;
+short __Complete_ParkingFee = 0x0650;
+short __Complete_TotalCost = 0x0660;
+short __Receipt_value = 0x0670;
+short __Animation_Price = 0x6010;
+short __receipt_backgroud = 0x0700;
+// ICON ID
+uint8_t _disappear = 0;
+uint8_t _disconnect = 1;
+uint8_t _connect = 2;
+uint8_t _warning = 3;
+uint8_t _arrow_dark = 4;
+uint8_t _arrow_light = 5;
+uint8_t _3G4G_disconnect = 6;
+uint8_t __3G4G_connect = 7;
+uint8_t _wifi_disconnect = 8;
+uint8_t _wifi_connect = 9;
+uint8_t _logo = 10;
+uint8_t _conn_map1 = 11;
+uint8_t _conn_map2 = 12;
+uint8_t _sel_gun_btn = 13;
+uint8_t _back_home_btn = 14;
+uint8_t _stop_charging_btn = 15;
+uint8_t _stop_charging_btn_scan = 16;
+uint8_t _chademo_dark = 17;
+uint8_t _ccs_dark = 18;
+uint8_t _gbt_dark = 19;
+uint8_t _actype_dark = 20;
+uint8_t _chademo_light = 21;
+uint8_t _ccs_light = 22;
+uint8_t _gbt_light = 23;
+uint8_t _actype_light = 24;
+uint8_t _main_none_rfid = 25;
+uint8_t _main_rfid = 26;
+uint8_t _main_none_app = 27;
+uint8_t _main_app = 28;
+uint8_t _main_none_qr = 29;
+uint8_t _main_qr = 30;
+uint8_t _charging_map1 = 31;
+uint8_t _charging_map2 = 32;
+uint8_t _battery_empty = 33;
+uint8_t _battery_cap_20 = 34;
+uint8_t _battery_cap_40 = 35;
+uint8_t _battery_cap_60 = 36;
+uint8_t _battery_cap_80 = 37;
+uint8_t _battery_cap_100 = 38;
+uint8_t _battery_map = 39;
+uint8_t _power_map = 40;
+uint8_t _time_map = 41;
+uint8_t _complete_map = 42;
+uint8_t _battery_soc_20 = 43;
+uint8_t _battery_soc_40 = 44;
+uint8_t _battery_soc_60 = 45;
+uint8_t _battery_soc_80 = 46;
+uint8_t _battery_soc_100 = 47;
+uint8_t _battery_eng_map = 48;
+uint8_t _money_map = 49;
+uint8_t _elapse_time_map = 50;
+uint8_t _charging_money = 51;
+//uint8_t _side_none_rfid       = 52;
+//uint8_t _side_rfid            = 53;
+//uint8_t _side_none_app        = 54;
+//uint8_t _side_app             = 55;
+//uint8_t _side_none_qr         = 56;
+//uint8_t _side_qr              = 57;
+uint8_t _eth_disconnect = 52; //58;
+uint8_t _eth_connect = 53; //59;
+
+uint8_t _chademo_dark_cmp = 54;
+uint8_t _ccs_dark_cmp = 55;
+uint8_t _gbt_dark_cmp = 56;
+uint8_t _actype_dark_cmp = 57;
+uint8_t _chademo_light_cmp = 58;
+uint8_t _ccs_light_cmp = 59;
+uint8_t _gbt_light_cmp = 60;
+uint8_t _actype_light_cmp = 61;
+
+uint8_t _logo_cmp = 62;
+uint8_t _battery_eng_trp_map = 63;
+uint8_t _money_trp_map = 64;
+uint8_t _elapse_time_trp_map = 65;
+#if defined DD360Audi
+////For Audi
+uint8_t _left_gun_disable_map = 66;
+uint8_t _left_gun_enable_map = 67;
+uint8_t _right_gun_disable_map = 68;
+uint8_t _right_gun_enable_map = 69;
+uint8_t _select_gun_btn = 70;
+uint8_t _emergency_disable_map = 72;
+// For replug
+struct timespec showReplugStrTimer;
+struct timespec showFullTargetTimer;
+short __show_StatusString_value_1 = 0x0460;
+short __show_StatusString_value_2 = 0x0462;
+uint8_t _showfulltarget_1 = 73;
+uint8_t _showfulltarget_2 = 74;
+uint8_t _showReplugStr_1 = 75;
+uint8_t _showReplugStr_2 = 76;
+// Select Gun for Audi
+short __show_selectgun_value = 0x0464;
+uint8_t _showselectgun_left = 77;
+uint8_t _showselectgun_right = 78;
+// Wait for gun plugin Audi
+short __show_waitgunplug_value = 0x0468;
+uint8_t _showwaitgunplug_left = 80;
+uint8_t _showwaitgunplug_right = 81;
+#else
+short __show_handshark_value = 0x0464;
+short __show_GFD_value = 0x0466;
+short __show_precharge_value = 0x0468;
+uint8_t _receipt_bk = 67;
+
+uint8_t _show_handshark_dark = 67;
+uint8_t _show_handshark_light = 68;
+uint8_t _show_GFD_dark = 69;
+uint8_t _show_GFD_light = 70;
+uint8_t _show_precharge_dark = 71;
+uint8_t _show_precharge_light = 72;
+#endif
+
+
 #endif //MODULE_LCM_CTRL_H_

+ 11 - 2
EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -345,16 +345,19 @@ static void checkChillerStatus(Gpio_out *gpio)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
     static ChillerInfo _chiller;
+    struct FanModuleData* ShmFanModuleData = (struct FanModuleData*)GetShmFanModuleData();;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[0].withChiller = TRUE;
     }
 
     if ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
             (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)) {
         chillerCount++;
+        ShmDcCommonData->pGunInfo[1].withChiller = TRUE;
     }
 
     if (chillerCount == 0) {
@@ -362,7 +365,9 @@ static void checkChillerStatus(Gpio_out *gpio)
         return;
     }
 
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++) {
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        if (!ShmDcCommonData->pGunInfo[gunIndex].withChiller)
+            continue;
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
@@ -380,6 +385,7 @@ static void checkChillerStatus(Gpio_out *gpio)
                 if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
                 {
                     pChillerInfo->ChillerSwitch = NO;
+                    ShmFanModuleData->SetFan1Speed = 0;
                 }
             }
             else
@@ -411,12 +417,15 @@ static void checkChillerStatus(Gpio_out *gpio)
     }
 
     uint8_t _chillerNeedOn = NO;
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++)
     {
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
         if(pChillerInfo->ChillerSwitch == YES)
         {
             _chillerNeedOn = YES;
+            if (chillerCount >= 2) {
+                ShmFanModuleData->SetFan1Speed = 7000;
+            }
         }
     }
 

+ 78 - 9
EVSE/Projects/DD360ComBox/Apps/ReadCmdline.c

@@ -210,11 +210,15 @@ void RunStatusProc(char *v1, char *v2)
 
         if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
             // get
-            printf ("index = %x, status = %x (%d)\n",
+            printf ("index = %x, status = %x (%d) Reservation is :%s\n",
                     _index,
                     pDcChargingInfo->SystemStatus,
-                    pDcChargingInfo->IsAvailable);
-            printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
+                    pDcChargingInfo->IsAvailable,
+                    ShmDcCommonData->pGunInfo[_index].ReservationStatus ? "trigger" : "expired");
+            if (ShmDcCommonData->pGunInfo[_index].ReservationStatus)
+                printf("Reservation idTag:%s\n", ShmDcCommonData->pGunInfo[_index].ReservationID);
+
+            printf("SystemTimeoutFlag = %d, PageIndex = %d\n",
                     pSysInfo->SystemTimeoutFlag, pSysInfo->PageIndex);
         } else {
             // set
@@ -335,6 +339,21 @@ void GetFwVerProc(void)
                      "      exit | c | C\n"
                      "      help | ? | h\n";
 
+
+    printf("ModelName = %s\r\n", pSysConfig->ModelName);
+    printf("DC Main Version = %s \n", pSysInfo->CsuRootFsFwRev);
+    printf("407 FW Version = %s\n", ShmPrimaryMcuData->version);
+    printf("Gun 0 FW Version = %s \n", pSysInfo->Connector1FwRev);
+    printf("Gun 1 FW Version = %s \n", pSysInfo->Connector2FwRev);
+    printf("Relay Board Version = %s \n", pSysInfo->RelayModuleFwRev);
+    printf("FAN Version = %s \n", pSysInfo->FanModuleFwRev);
+    printf("LED Version = %s \n", pSysInfo->LedModuleFwRev);
+    printf("LCM FW Version = V.%03d \n", ShmDcCommonData->LcmFwVersion);
+    printf("Dispenser Network Information checked: IP = % s Netmask = % s, Gateway = % s \n",
+        pSysConfig->Eth0Interface.EthIpAddress,
+        pSysConfig->Eth0Interface.EthSubmaskAddress,
+        pSysConfig->Eth0Interface.EthGatewayAddress);
+    /*
     while (isContinue) {
         if (readCmdKey(CMD_KEY_WAIT) == NO) {
             continue;
@@ -379,6 +398,7 @@ void GetFwVerProc(void)
         }
 
     }//while
+    */
 }
 
 void CreateOneError(char *v1)
@@ -476,6 +496,7 @@ void GetSystemInfo()
     printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
             pSysConfig->MaxChargingPower,
             pSysConfig->MaxChargingCurrent);
+    pSysConfig->ShowInformation = YES;
 }
 
 void ChangeGunNum()
@@ -538,6 +559,7 @@ void SetDebugMode(char *v1)
     int mode = atoi(v1);
 
     ShmDcCommonData->debugflag = mode;
+    pSysConfig->ShowInformation = mode;
     printf("Set Debug Mode:%d\n" , ShmDcCommonData->debugflag);
 }
 
@@ -723,6 +745,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         return;
     }
     //kill ev task
+    ShmDcCommonData->debugflag = YES;
     system("killall Module_EvComm");
 
     pSysInfo->CurGunSelected = _GunIndex;
@@ -947,7 +970,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             pDcChargingInfo->PresentChargingPower = 0;
 
             if (stopChg == pSysConfig->TotalConnectorCount) {
-
+                ShmDcCommonData->debugflag = NO;
                 system("/root/Module_EvComm &");
                 sleep(3);
 
@@ -1194,6 +1217,7 @@ static void writeOTPTemp(void)
         usleep(sleepTime);
     }//while
 }
+
 void writeChillerStatus(char *v1)
 {
     if (ShmDcCommonData->debugflag == YES) {
@@ -1205,6 +1229,35 @@ void writeChillerStatus(char *v1)
     } else
         printf("Please open Debug mode\n");
 }
+
+void showNetworkPage(char* v1)
+{
+    ShmDcCommonData->showNetPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showNetPackage)
+        printf("Show Network Package on\n");
+    else
+        printf("Show Network Package off\n");
+}
+
+void showCANBUSPage(char* v1)
+{
+    ShmDcCommonData->showCanPackage = atoi(newString[1]);
+    if (ShmDcCommonData->showCanPackage)
+        printf("Show CAN Bus Package on\n");
+    else
+        printf("Show CAN Bus Package off\n");
+}
+void setSystemTime(char* date,char* time)
+{
+    char _setTime[30];
+    char cmdBuf[50];
+    sprintf(_setTime, "%s %s", date, time);
+    printf("Set Timer:%s", _setTime);
+    sprintf((char*)cmdBuf, "date -u -s \"%s\" >> /dev/null &", _setTime);
+    system((char*)cmdBuf);
+    system("hwclock -w -u");
+    system("hwclock -s");
+}
 static void writeGunAndChillerTemp(void)
 {
     uint8_t _GunIndex = 0;
@@ -1280,7 +1333,16 @@ static void writeGunAndChillerTemp(void)
         usleep(sleepTime);
     }//while
 }
+void ShowPowerConsumption(char* v1)
+{
+    printf("Dispenser Gun0 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[0].PowerConsumption);
+    printf("Dispenser Gun1 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[1].PowerConsumption);
 
+    printf("Power Consumption Gun1:%.4f, Gun2:%.4f, Gun3:%.4f, Gun4:%.4f", ShmDcCommonData->pConsumption.Gun1_Consumption,
+        ShmDcCommonData->pConsumption.Gun2_Consumption,
+        ShmDcCommonData->pConsumption.Gun3_Consumption,
+        ShmDcCommonData->pConsumption.Gun4_Consumption);
+}
 int main(void)
 {
     uint8_t _GunIndex = 0;
@@ -1305,7 +1367,10 @@ int main(void)
                      "       tempW                             : write connector header and Chiller temperature\r\n"
                      "       tempR                             : print connector header and chiller temperature\r\n"
                      "       OTP                               : Write OTP temperature\r\n"
-                     "       chiller                           : set chiller on/off"
+                     "       chiller                           : set chiller on/off\r\n"
+                     "       netdump                           : show network package\r\n"
+                     "       candump                           : show can package\r\n"
+                     "       powerconsumption                  : Show Power Consumption\n"
                      "\r\n";
 
     if (CreateAllCsuShareMemory() == FAIL) {
@@ -1456,10 +1521,6 @@ int main(void)
             }
             SetChargingInfoCCID(newString[1], newString[2]);
         } else if (strcmp(newString[0], "strchg") == 0) {
-            if (ShmDcCommonData->debugflag == NO ) {
-                printf("Please Open debug mode\n");
-                continue;
-            }
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             if (strcmp(newString[1], "auto") == 0) {
                 newString[2][0] = 0;
@@ -1482,6 +1543,14 @@ int main(void)
             writeOTPTemp();
         } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
             writeChillerStatus(newString[1]);
+        } else if (strcmp(newString[0], "netdump") == 0) { //印出網路封包
+            showNetworkPage(newString[1]);
+        } else if (strcmp(newString[0], "candump") == 0) { //印出網路封包
+            showCANBUSPage(newString[1]);
+        } else if (strcmp(newString[0], "time") == 0) {  //設定系統時間
+            setSystemTime(newString[1], newString[2]);
+        } else if (strcmp(newString[0], "powerconsumption") == 0) { // Power Consumption
+            ShowPowerConsumption(newString[1]);
         } else {
             printf("%s\n", usageMsg);
         }

+ 5 - 1
EVSE/Projects/DD360ComBox/Apps/SelectGun/SelectGun.h

@@ -61,7 +61,11 @@ typedef struct StPricesInfo {
     //float TotalCost;            //unit = 0.01 dollar, value / 100
     float Balance;              //unit = 0.01 dollar, value / 100
     //float DefaultPrices;        //unit = 0.01 dollar, value / 100
-    uint8_t Reserved[4];
+    float Discount;
+    int TransactionId;
+    float EnergyCost;
+    float ParkingFee;
+    float RemainAmount;
 } PricesInfo;
 
 //typedef struct StOperativeInfo {

+ 44 - 7
EVSE/Projects/DD360ComBox/Apps/ShareMemory/shmMem.c

@@ -38,6 +38,7 @@ static struct FanModuleData *ShmFanModuleData = NULL;
 static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct LedModuleData *ShmLedModuleData = NULL;
 static struct OCPP16Data *ShmOCPP16Data = NULL;
+static struct OCPP20Data* ShmOCPP20Data = NULL;
 
 static SelectGunInfo *ShmSelectGunInfo = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
@@ -300,6 +301,15 @@ void *GetShmOCPP16Data(void)
     return ShmOCPP16Data;
 }
 
+void* GetShmOCPP20Data(void)
+{
+    if (ShmOCPP20Data == NULL) {
+        return NULL;
+    }
+
+    return ShmOCPP20Data;
+}
+
 void *GetShmSelectGunInfo(void)
 {
     if (ShmSelectGunInfo == NULL) {
@@ -604,6 +614,21 @@ int InitOCPPShmMem(void)
     return PASS;
 }
 
+int InitOCPP20ShmMem(void)
+{
+    int MeterSMId = FAIL;
+
+    if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) {
+        log_info("Get OCPP20 share memory error");
+        return FAIL;
+    } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void*)-1) {
+        log_info("Create OCPP20 share memory error");
+        return FAIL;
+    }
+
+    return PASS;
+}
+
 int InitLEDShmMem(void)
 {
     int MeterSMId = FAIL;
@@ -905,16 +930,15 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
         }
         break;
 
+    case 'V': // Liquid CCS1 combo
+    case 'F': // Liquid CCS2 combo
     case 'T': // Rema CCS1
     case 'D': // Rema CCS2
     case 'U': // CCS1 combo
     case 'E': // CCS2 combo
-    case 'V': // Liquid CCS1 combo
-    case 'F': // Liquid CCS2 combo
     case 'M': // 80A CCS2
     case 'N': // 80A CCS1
-    case 'P': // Phoenix CCS2 500A 水冷
-    case 'R': // Phoenix CCS1 500A 水冷
+    case 'P': // 急電弓
         if (CCS_QUANTITY > gGunIndexInfo.CcsIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->CcsChargingData[gGunIndexInfo.CcsIndex];
 
@@ -934,16 +958,25 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
                 gGunIndexInfo.CcsIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
-            if(typeValue == 'P')
-            {
+            if(typeValue == 'P') {
                 pDcChargingInfo->PantographFlag = YES;
-            }
+            } else if (typeValue == 'V') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Liquid;
+            } else if (typeValue == 'F') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Liquid;
+            } else if (typeValue == 'T' || typeValue == 'U' || typeValue == 'N') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS1_Natural;
+            } else if (typeValue == 'D' || typeValue == 'E' || typeValue == 'M') {
+                pDcChargingInfo->CCSGunType = _TYPE_CCS2_Natural;
+            } else
+                pDcChargingInfo->CCSGunType = _TYPE_CCS_NONE;
         } else {
             result = false;
         }
         break;
 
     case 'G':  // GBT DC
+    case 'B': // GBT YG PT100
         if (GB_QUANTITY > gGunIndexInfo.GbIndex) {
             pDcChargingInfo = (struct ChargingInfoData *)&pSysInfo->GbChargingData[gGunIndexInfo.GbIndex];
 
@@ -1114,6 +1147,10 @@ int CreateAllCsuShareMemory(void)
         return ret;
     }
 
+    if ((ret = InitOCPP20ShmMem()) == FAIL) {
+        return ret;
+    }
+
     if ((ret = InitSelectGunShmMem()) == FAIL) {
         return ret;
     }

+ 1 - 0
EVSE/Projects/DD360ComBox/Apps/ShareMemory/shmMem.h

@@ -42,6 +42,7 @@ void *GetShmSysInfoData(void);
 void *GetShmSysWarningInfo(void);
 
 void *GetShmOCPP16Data(void);
+void* GetShmOCPP20Data(void);
 
 void *GetShmCHAdeMOData(void);
 void *GetShmGBTData(void);

+ 1 - 0
EVSE/Projects/define.h

@@ -628,6 +628,7 @@ struct ChargingInfoData
 	int EvBatterySoc;				// 0~100%
 	unsigned char ConnectorPlugIn;			//0: unplug, 1: Plug-in
 	unsigned char GunLocked;				//0: unlocked 1: locked
+	unsigned char InProgress;			    //0: real idle, 1: session(transaction) in progress
 	float PilotVoltage;
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott