浏览代码

[Improve][Added][Module_LcmControl.c]
2022-10-19 / EASON YANG
Action:
1. Added: CDFA variable structure.
2. Improve: setFinalCost() function. For CDFA 2.0
3. Improve: setRunningCost() fucntion. FOR CDFA 2.0

File:
1, Module_LcmControl.c
Action 1
Action 2
Action 3

LCM VERSION: V0.31

8009 2 年之前
父节点
当前提交
87fe2736f7
共有 2 个文件被更改,包括 738 次插入61 次删除
  1. 737 61
      EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c
  2. 1 0
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h

+ 737 - 61
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c

@@ -109,6 +109,29 @@ enum TMR_IDX
 
 struct timespec					startTime[AC_QUANTITY][TMR_IDX_FINAL_COUNTER];
 
+//=======================================
+// Declare Variable CDFA 2.0
+//=======================================
+struct StrcutLcmRunningCost
+{
+	unsigned char PREVIOUS_TIMESTAMP[36];
+	unsigned char PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES[36];
+	unsigned int PREVIOUS_METER_VALUE;
+	unsigned int PREVIOUS_REAL_TIME_IN_SECONDS;
+	double PREVIOUS_HOUR_PRICE;
+	double PREVIOUS_KWH_PRICE;
+	double END_OF_SESSION_KWH_PRICE;
+	double END_OF_SESSION_HOUR_PRICE;
+	double END_OF_SESSION_IDLE_PRICE;
+	unsigned int GRACE_MINUTES_PERIOD_COUNTER;
+};
+
+struct StructCaliforniaPricing
+{
+	struct StrcutLcmRunningCost		LcmRunningCost[AC_QUANTITY];
+
+}CaliforniaPricing;
+
 #define TIME_ANIMATION_PLUGIN			1 // Unit: Second
 #define TIME_ANIMATION_BATTERY			1 // Unit: Second
 #define TIME_ANIMATION_CONNECTION		1 // Unit: Second
@@ -286,6 +309,128 @@ uint8_t split(char **arr, char *str, const char *del)
 	return result;
 }
 
+int DiffTimebWithNowSec(struct timeb ST)
+{
+	//return milli-second
+	struct timeb ET;
+	unsigned int StartTime,StopTime;
+
+	ftime(&ET);
+	StartTime=(unsigned int)ST.time;
+	StopTime=(unsigned int)ET.time;
+	return (StopTime-StartTime);
+}
+
+int ElapsedTime(uint8_t *start)
+{
+	int time = 0;
+	struct ParsingResult
+	{
+		int result;
+		int scanedElement;
+		int year;
+		int month;
+		int mday;
+		int hour;
+		int min;
+		int sec;
+		int tz_hour;
+		int tz_min;
+		float minSec;
+	}parsingResult;
+
+	struct tm tmStart;
+	struct timeb tbStart;
+
+	memset(&parsingResult, 0x00, sizeof(struct ParsingResult));
+
+	if(strstr((char*)start, ".") != NULL)
+	{
+		// Original data with mini second
+		if(strstr((char*)start, "Z") != NULL)
+		{
+			// Original data with Z
+			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%fZ",
+																&parsingResult.year,
+																&parsingResult.month,
+																&parsingResult.mday,
+																&parsingResult.hour,
+																&parsingResult.min,
+																&parsingResult.sec,
+																&parsingResult.minSec);
+		}
+		else
+		{
+			// Original data without Z
+			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%f%d:%d",
+												&parsingResult.year,
+												&parsingResult.month,
+												&parsingResult.mday,
+												&parsingResult.hour,
+												&parsingResult.min,
+												&parsingResult.sec,
+												&parsingResult.minSec,
+												&parsingResult.tz_hour,
+												&parsingResult.tz_min);
+		}
+	}
+	else
+	{
+		// Original data without mini second
+		if(strstr((char*)start, "Z") != NULL)
+		{
+			// Original data with Z
+			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%dZ",
+												&parsingResult.year,
+												&parsingResult.month,
+												&parsingResult.mday,
+												&parsingResult.hour,
+												&parsingResult.min,
+												&parsingResult.sec);
+		}
+		else
+		{
+			// Original data without Z
+			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d%d:%d",
+												&parsingResult.year,
+												&parsingResult.month,
+												&parsingResult.mday,
+												&parsingResult.hour,
+												&parsingResult.min,
+												&parsingResult.sec,
+												&parsingResult.tz_hour,
+												&parsingResult.tz_min);
+		}
+	}
+
+	if(parsingResult.scanedElement >= 6)
+	{
+		tmStart.tm_year = parsingResult.year - 1900;
+		tmStart.tm_mon = parsingResult.month - 1;
+		tmStart.tm_mday = parsingResult.mday;
+		tmStart.tm_hour = parsingResult.hour;
+		tmStart.tm_min = parsingResult.min;
+		tmStart.tm_sec = parsingResult.sec;
+		tmStart.tm_gmtoff = 0;
+		tbStart.time = mktime(&tmStart);
+		tbStart.timezone = 0;
+		tbStart.millitm = 0;
+
+		tbStart.time -= (parsingResult.tz_hour*3600) + (parsingResult.tz_min*60*(parsingResult.tz_hour>=0?1:-1));
+
+		if(DiffTimebWithNowSec(tbStart) <= 0)
+			time = 0;
+		else
+			time = DiffTimebWithNowSec(tbStart);
+	}
+	else
+	{
+		DEBUG_WARN("Start date parsing error.\n");
+	}
+
+	return time;
+}
+
 void getDateTimeString(char* result)
 {
 	struct ParsingResult
@@ -1523,7 +1668,7 @@ float getPresentFinalCost(uint8_t gun_index)
 }
 
 //=======================================
-// Setting [ Billing ] ( BACKEND )
+// SETTING BACKEND [BILLING]
 //=======================================
 void setBillingFromBackend(uint8_t gun_index, uint8_t system_mode)
 {
@@ -1623,7 +1768,7 @@ void setBillingFromBackend(uint8_t gun_index, uint8_t system_mode)
 }
 
 //=======================================
-// Setting [ UserPrice ] ( BACKEND )
+// SETTING BACKEDN [USER PRICE]
 //=======================================
 void setUserPrice(uint8_t type)
 {
@@ -1708,7 +1853,7 @@ void setUserPrice(uint8_t type)
 }
 
 //=======================================
-// Setting [ FinalCost ] ( BACKEND )
+// SETTING BACKEND [FINAL COST]
 //=======================================
 void setFinalCost(uint8_t gun_index, uint8_t type)
 {
@@ -1717,13 +1862,15 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 	unsigned char balance_empty[32];
 	unsigned char session_empty[32];
 	unsigned char occupancy_empty[32];
+	unsigned char priceText[1024];
 	json_object *jsonDescription;
 
 	memset(output_data, 0x00, ARRAY_SIZE(output_data));
-	memset(balance_empty, 0x00, ARRAY_SIZE(balance_empty));
 	memset(cost_empty, 0x00, ARRAY_SIZE(cost_empty));
+	memset(balance_empty, 0x00, ARRAY_SIZE(balance_empty));
 	memset(session_empty, 0x00, ARRAY_SIZE(session_empty));
 	memset(occupancy_empty, 0x00, ARRAY_SIZE(occupancy_empty));
+	memset(priceText, 0x00, ARRAY_SIZE(priceText));
 
 	switch(type)
 	{
@@ -1742,18 +1889,84 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double chargingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+					if((strcmp((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description,"") != 0))
+					{
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double chargingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
 
-					if(!is_error(jsonDescription))
+						if(!is_error(jsonDescription))
+						{
+							if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+							{
+								chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							}
+
+							if(chargingCost> 0)
+								sprintf((char*)output_data, "$ %.2f", chargingCost);
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							// APPEAR COST ICON
+							setDisplayValue(ICON_CHARGING_SESSION_FEE, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_SESSION_FEE, output_data, ARRAY_SIZE(output_data));
+						}
+						json_object_put(jsonDescription);
+					}
+					else
 					{
-						if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						double FLAT_FEE = 0;
+						double INPUT_COST = 0;
+						double OUTPUT_COST = 0;
+						double END_OF_SESSION_HOUR_PRICE = 0;
+						double END_OF_SESSION_IDLE_PRICE = 0;
+
+						// Final cost [Cost]
+						if(ShmOCPP16Data->Cost.FinalCost[gun_index].cost != 0)
 						{
-							chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							INPUT_COST = ShmOCPP16Data->Cost.FinalCost[gun_index].cost;
+
+							// Running cost [Flat fee]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+							{
+								FLAT_FEE = ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee;
+							}
+
+							// Running cost [Hour price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+							{
+								if(CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE > 0)
+								{
+									// Save at last [Hour price] from running cost
+									END_OF_SESSION_HOUR_PRICE = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE;
+								}
+							}
+
+							// Running cost [Idle -> Hour price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice != 0)
+							{
+								if(CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE > 0)
+								{
+									// Save at last [Idle -> Hour price] from running cost
+									END_OF_SESSION_IDLE_PRICE = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE;
+								}
+							}
+
+							// Running cost [kWh price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+							{
+								// [Cost] - [Flat fee] - [Hour price] - [Idle -> Hour price] = [kWh price]
+								OUTPUT_COST = INPUT_COST - FLAT_FEE - END_OF_SESSION_HOUR_PRICE - END_OF_SESSION_IDLE_PRICE;
+							}
 						}
 
-						if(chargingCost> 0)
-							sprintf((char*)output_data, "$ %.2f", chargingCost);
+						if(OUTPUT_COST > 0)
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
 						else
 							sprintf((char*)output_data, "$ -----");
 
@@ -1761,7 +1974,6 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 						setDisplayValue(ICON_CHARGING_SESSION_FEE, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_SESSION_FEE, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -1782,25 +1994,89 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double parkingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+					if((strcmp((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description,"") != 0))
+					{
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double parkingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
 
-					if(!is_error(jsonDescription))
+						if(!is_error(jsonDescription))
+						{
+							if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+							{
+								parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							}
+
+							if(parkingCost > 0)
+								sprintf((char*)output_data, "$ %.2f", parkingCost);
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							setDisplayValue(ICON_CHARGING_PARKING_FEE, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_PARKING_FEE, output_data, ARRAY_SIZE(output_data));
+						}
+						json_object_put(jsonDescription);
+					}
+					else
 					{
-						if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						double INPUT_COST = 0;
+						double OUTPUT_COST = 0;
+						double FLAT_FEE = 0;
+						double END_OF_SESSION_KWH_PRICE = 0;
+						double END_OF_SESSION_IDLE_PRICE = 0;
+
+						// Final cost [Cost]
+						if(ShmOCPP16Data->Cost.FinalCost[gun_index].cost != 0)
 						{
-							parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							INPUT_COST = ShmOCPP16Data->Cost.FinalCost[gun_index].cost;
+
+							// Running cost [Flat fee]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+							{
+								FLAT_FEE = ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee;
+							}
+
+							// Running cost [kWh price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+							{
+								if(CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE > 0)
+								{
+									// Save at last [kWh price] from running cost
+									END_OF_SESSION_KWH_PRICE = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE;
+								}
+							}
+
+							// Running cost [Idle -> Hour price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice != 0)
+							{
+								if(CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE > 0)
+								{
+									// Save at last [Idle -> Hour price] from running cost
+									END_OF_SESSION_IDLE_PRICE = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE;
+								}
+							}
+
+							// [Hour price] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+							{
+								// [Cost] - [Flat fee] - [kWh price] - [Idle -> Hour price] = [Hour price]
+								OUTPUT_COST = INPUT_COST - FLAT_FEE - END_OF_SESSION_KWH_PRICE - END_OF_SESSION_IDLE_PRICE;
+							}
 						}
 
-						if(parkingCost > 0)
-							sprintf((char*)output_data, "$ %.2f", parkingCost);
+						if(OUTPUT_COST > 0)
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
 						else
 							sprintf((char*)output_data, "$ -----");
 
 						setDisplayValue(ICON_CHARGING_PARKING_FEE, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_PARKING_FEE, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -1821,24 +2097,53 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double chargingCost = 0;
-					double parkingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
-
-					if(!is_error(jsonDescription))
+					if((strcmp((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description,"") != 0))
 					{
-						if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double chargingCost = 0;
+						double parkingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+
+						if(!is_error(jsonDescription))
 						{
-							chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+							{
+								chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							}
+
+							if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+							{
+								parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							}
+
+							if((chargingCost + parkingCost) > 0)
+								sprintf((char*)output_data, "$ %.2f", (chargingCost + parkingCost));
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							// APPEAR COST ICON
+							setDisplayValue(ICON_CHARGING_TOTAL_COST, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_TOTAL_COST, output_data, ARRAY_SIZE(output_data));
 						}
+						json_object_put(jsonDescription);
+					}
+					else
+					{
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						double OUTPUT_COST = 0;
 
-						if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+						// Final cost [Cost]
+						if(ShmOCPP16Data->Cost.FinalCost[gun_index].cost != 0)
 						{
-							parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							OUTPUT_COST = ShmOCPP16Data->Cost.FinalCost[gun_index].cost;
 						}
 
-						if((chargingCost + parkingCost) > 0)
-							sprintf((char*)output_data, "$ %.2f", (chargingCost + parkingCost));
+						if(OUTPUT_COST > 0)
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
 						else
 							sprintf((char*)output_data, "$ -----");
 
@@ -1846,7 +2151,6 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 						setDisplayValue(ICON_CHARGING_TOTAL_COST, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_TOTAL_COST, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -1896,13 +2200,23 @@ void setFinalCost(uint8_t gun_index, uint8_t type)
 				// OCPP 2.0.1
 			}
 			break;
+		case PRICE_TEXT:
+			if(ShmOCPP16Data->StopTransaction[gun_index].TransactionId != ShmOCPP16Data->Cost.FinalCost[gun_index].txId)
+			{
+
+			}
+			else
+			{
+				memcpy((char*) priceText,(char*)ShmOCPP16Data->Cost.FinalCost[gun_index].priceText,ARRAY_SIZE(priceText));
+			}
+			break;
 		default:
 			break;
 	}
 }
 
 //=======================================
-// Setting [ RunningCost ] ( BACKEND )
+// SETTING BACKEND [RUNNING COST]
 //=======================================
 void setRunningCost(uint8_t gun_index, uint8_t type)
 {
@@ -1934,18 +2248,117 @@ void setRunningCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double chargingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
+					if((strcmp((char *)&ShmOCPP16Data->Cost.RunningCost[gun_index].description,"") != 0))
+					{
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double chargingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
 
-					if(!is_error(jsonDescription))
+						if(!is_error(jsonDescription))
+						{
+							if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+							{
+								chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							}
+
+							if(chargingCost> 0)
+								sprintf((char*)output_data, "$ %.2f", chargingCost);
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							// APPEAR COST ICON
+							setDisplayValue(ICON_CHARGING_SESSION_FEE, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_SESSION_FEE, output_data, ARRAY_SIZE(output_data));
+						}
+						json_object_put(jsonDescription);
+					}
+					else
 					{
-						if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						double INPUT_COST = 0;
+						double OUTPUT_COST = 0;
+						double FLAT_FEE = 0;
+						double PRESENT_KWH_PRICE = 0;
+						double PREVIOUS_KWH_PRICE = 0;
+						double PRESENT_HOUR_PRICE = 0;
+
+						if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Charging") == 0)
 						{
-							chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							// Running cost [Cost]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].cost != 0)
+							{
+								INPUT_COST = ShmOCPP16Data->Cost.RunningCost[gun_index].cost;
+							}
+
+							// Running cost [Flat fee]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+							{
+								FLAT_FEE = ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee;
+							}
+
+							// Running cost [Hour price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+							{
+								if((strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp, "") != 0) && (ElapsedTime(ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp) > 0))
+								{
+									PRESENT_HOUR_PRICE = (((float)ElapsedTime(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice);
+									if(strcmp((char*)CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, (char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp) != 0)
+									{
+										CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE = PRESENT_HOUR_PRICE + CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE;
+										strcpy((char*)CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, (char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp);
+									}
+								}
+								else
+								{
+									CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE = 0;
+									memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP));
+								}
+							}
+							else
+							{
+								CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE = 0;
+								memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP));
+							}
+
+							// Running cost [kWh price]
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+							{
+								PREVIOUS_KWH_PRICE = INPUT_COST;
+								if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+								{
+									PREVIOUS_KWH_PRICE = INPUT_COST - FLAT_FEE;
+									if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+									{
+										PREVIOUS_KWH_PRICE = INPUT_COST - FLAT_FEE - CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE;
+									}
+								}
+								else
+								{
+									if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+									{
+										PREVIOUS_KWH_PRICE = INPUT_COST - CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE;
+									}
+								}
+
+								PRESENT_KWH_PRICE = ((float)(((ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10) - ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue)/1000.00)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice);
+								OUTPUT_COST = PREVIOUS_KWH_PRICE + PRESENT_KWH_PRICE;
+								CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE = OUTPUT_COST;
+							}
 						}
+						else if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Idle") == 0)
+						{
+							// Shown at last value for kWh price
+							OUTPUT_COST = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE;
+						}
+						else
+						{}
 
-						if(chargingCost> 0)
-							sprintf((char*)output_data, "$ %.2f", chargingCost);
+						if(OUTPUT_COST > 0)
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
 						else
 							sprintf((char*)output_data, "$ -----");
 
@@ -1953,7 +2366,6 @@ void setRunningCost(uint8_t gun_index, uint8_t type)
 						setDisplayValue(ICON_CHARGING_SESSION_FEE, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_SESSION_FEE, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -1974,25 +2386,124 @@ void setRunningCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double parkingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
+					if((strcmp((char *)&ShmOCPP16Data->Cost.RunningCost[gun_index].description,"") != 0))
+					{
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double parkingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
 
-					if(!is_error(jsonDescription))
+						if(!is_error(jsonDescription))
+						{
+							if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+							{
+								parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							}
+
+							if(parkingCost > 0)
+								sprintf((char*)output_data, "$ %.2f", parkingCost);
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							setDisplayValue(ICON_CHARGING_PARKING_FEE, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_PARKING_FEE, output_data, ARRAY_SIZE(output_data));
+						}
+						json_object_put(jsonDescription);
+					}
+					else
 					{
-						if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						double INPUT_COST = 0;
+						double OUTPUT_COST = 0;
+						double FLAT_FEE = 0;
+						double PRESENT_KWH_PRICE = 0;
+						double PREVIOUS_HOUR_PRICE = 0;
+						double PRESENT_HOUR_PRICE = 0;
+
+						if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Charging") == 0)
+						{
+							// [Cost] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].cost != 0)
+							{
+								INPUT_COST = ShmOCPP16Data->Cost.RunningCost[gun_index].cost;
+							}
+
+							// [Flat fee] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+							{
+								FLAT_FEE = ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee;
+							}
+
+							// [kWh price] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+							{
+								if((ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue != 0) || (((ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10) - ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue) != 0))
+								{
+									PRESENT_KWH_PRICE = ((float)(((ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10) - CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE)/1000.00)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice);
+									if(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE != ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue)
+									{
+										CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE = PRESENT_KWH_PRICE + CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE;
+										CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE = ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue;
+									}
+								}
+								else
+								{
+									CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE = 0;
+									CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE = 0;
+								}
+							}
+							else
+							{
+								CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE = 0;
+								CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE = 0;
+							}
+
+							// [Hour price] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+							{
+								PREVIOUS_HOUR_PRICE = INPUT_COST;
+								if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.flatFee != 0)
+								{
+									PREVIOUS_HOUR_PRICE = INPUT_COST - FLAT_FEE;
+									if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+									{
+										PREVIOUS_HOUR_PRICE = INPUT_COST - FLAT_FEE - CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE;
+									}
+								}
+								else
+								{
+									if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+									{
+										PREVIOUS_HOUR_PRICE = INPUT_COST - CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE;
+									}
+								}
+
+								PRESENT_HOUR_PRICE = (((float)ElapsedTime(ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice);
+								OUTPUT_COST = PRESENT_HOUR_PRICE + PREVIOUS_HOUR_PRICE;
+								CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE = OUTPUT_COST;
+							}
+						}
+						else if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Idle") == 0)
 						{
-							parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							// Shown at last value for [Hour price]
+							OUTPUT_COST = CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE;
 						}
+						else
+						{}
 
-						if(parkingCost > 0)
-							sprintf((char*)output_data, "$ %.2f", parkingCost);
+						if(OUTPUT_COST > 0)
+						{
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
+						}
 						else
 							sprintf((char*)output_data, "$ -----");
 
 						setDisplayValue(ICON_CHARGING_PARKING_FEE, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_PARKING_FEE, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -2013,24 +2524,158 @@ void setRunningCost(uint8_t gun_index, uint8_t type)
 				}
 				else
 				{
-					double chargingCost = 0;
-					double parkingCost = 0;
-					jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
-
-					if(!is_error(jsonDescription))
+					if((strcmp((char *)&ShmOCPP16Data->Cost.RunningCost[gun_index].description,"") != 0))
 					{
-						if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+						//========================
+						// CDFA 1.0 Structure
+						//========================
+						double chargingCost = 0;
+						double parkingCost = 0;
+						jsonDescription = json_tokener_parse((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].description);
+
+						if(!is_error(jsonDescription))
 						{
-							chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							if(json_object_object_get(jsonDescription,"chargingFee") != NULL)
+							{
+								chargingCost += json_object_get_double(json_object_object_get(jsonDescription,"chargingFee"));
+							}
+
+							if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+							{
+								parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							}
+
+							if((chargingCost + parkingCost) > 0)
+								sprintf((char*)output_data, "$ %.2f", (chargingCost + parkingCost));
+							else
+								sprintf((char*)output_data, "$ -----");
+
+							// APPEAR COST ICON
+							setDisplayValue(ICON_CHARGING_TOTAL_COST, APPEAR);
+							lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_TOTAL_COST, output_data, ARRAY_SIZE(output_data));
 						}
+						json_object_put(jsonDescription);
+					}
+					else
+					{
+						//========================
+						// CDFA 2.0 Structure
+						//========================
+						int GRACE_MINUTES_IN_SECONDS = 0;
+						int TOTAL_REAL_TIME_IN_SECONDS = 0;
+						int PRESENT_REAL_TIME_IN_SECONDS = 0;
+						double INPUT_COST = 0;
+						double OUTPUT_COST = 0;
+						double PRESENT_KWH_PRICE = 0;
+						double PRESENT_HOUR_PRICE = 0;
+						double PRESENT_IDLE_PRICE = 0;
+
+						if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Charging") == 0)
+						{
+							// [Cost] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].cost != 0)
+							{
+								INPUT_COST = ShmOCPP16Data->Cost.RunningCost[gun_index].cost;
+							}
 
-						if(json_object_object_get(jsonDescription,"parkingFee") != NULL)
+							// [kWh price] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice != 0)
+							{
+								if((ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue != 0) || (((ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10) - ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue) != 0))
+								{
+									PRESENT_KWH_PRICE = ((float)(((ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10) - ShmOCPP16Data->Cost.RunningCost[gun_index].meterValue)/1000.00)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.kWhPrice);
+								}
+							}
+
+							// [Hour price] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice != 0)
+							{
+								if((strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp, "") != 0) && (ElapsedTime(ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp) > 0))
+								{
+									PRESENT_HOUR_PRICE = (((float)ElapsedTime(ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].chargingPrice.hourPrice);
+								}
+							}
+
+							OUTPUT_COST = INPUT_COST + PRESENT_KWH_PRICE + PRESENT_HOUR_PRICE;
+						}
+						else if(strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].state ,"Idle") == 0)
 						{
-							parkingCost += json_object_get_double(json_object_object_get(jsonDescription,"parkingFee"));
+							// [Cost] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].cost != 0)
+							{
+								INPUT_COST = ShmOCPP16Data->Cost.RunningCost[gun_index].cost;
+							}
+
+							// [Grace minutes] sending from the central system
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.graceMinutes != 0)
+							{
+								GRACE_MINUTES_IN_SECONDS = (ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.graceMinutes*60);
+							}
+
+							// Calculation total real time
+							if((strcmp((char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp, "") != 0) && (ElapsedTime(ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp) > 0))
+							{
+								PRESENT_REAL_TIME_IN_SECONDS = ElapsedTime(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES);
+								if(strcmp((char*)CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, (char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp) != 0)
+								{
+									CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS = PRESENT_REAL_TIME_IN_SECONDS + CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS;
+									strcpy((char*)CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, (char*)ShmOCPP16Data->Cost.RunningCost[gun_index].timestamp);
+
+									CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER++;
+								}
+
+								TOTAL_REAL_TIME_IN_SECONDS = PRESENT_REAL_TIME_IN_SECONDS + CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS;
+							}
+
+							if(ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice != 0)
+							{
+								if(ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.graceMinutes != 0)
+								{
+									if(TOTAL_REAL_TIME_IN_SECONDS >= GRACE_MINUTES_IN_SECONDS)
+									{
+										if(CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER == 1)
+										{
+											PRESENT_IDLE_PRICE = (((float)(PRESENT_REAL_TIME_IN_SECONDS - GRACE_MINUTES_IN_SECONDS)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice);
+											OUTPUT_COST = INPUT_COST + PRESENT_IDLE_PRICE;
+										}
+										else
+										{
+											PRESENT_IDLE_PRICE = (((float)(PRESENT_REAL_TIME_IN_SECONDS)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice);
+											OUTPUT_COST = INPUT_COST + PRESENT_IDLE_PRICE;
+										}
+
+										CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = (((float)(TOTAL_REAL_TIME_IN_SECONDS - GRACE_MINUTES_IN_SECONDS)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice);
+									}
+									else
+									{
+										// A user completed the session before grace minutes start counting.
+										CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = 0;
+										OUTPUT_COST = INPUT_COST;
+									}
+								}
+								else
+								{
+									PRESENT_IDLE_PRICE = (((float)(PRESENT_REAL_TIME_IN_SECONDS)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice);
+									OUTPUT_COST = INPUT_COST + PRESENT_IDLE_PRICE;
+
+									CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = (((float)(TOTAL_REAL_TIME_IN_SECONDS)/3600)*ShmOCPP16Data->Cost.RunningCost[gun_index].idlePrice.hourPrice);
+									CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER = 0;
+								}
+							}
+							else
+							{
+								CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = 0;
+								CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER = 0;
+								memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES));
+
+								OUTPUT_COST = INPUT_COST;
+							}
 						}
+						else
+						{}
 
-						if((chargingCost + parkingCost) > 0)
-							sprintf((char*)output_data, "$ %.2f", (chargingCost + parkingCost));
+						if(OUTPUT_COST > 0)
+							sprintf((char*)output_data, "$ %.2f", OUTPUT_COST);
 						else
 							sprintf((char*)output_data, "$ -----");
 
@@ -2038,7 +2683,6 @@ void setRunningCost(uint8_t gun_index, uint8_t type)
 						setDisplayValue(ICON_CHARGING_TOTAL_COST, APPEAR);
 						lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_CHARGING_TOTAL_COST, output_data, ARRAY_SIZE(output_data));
 					}
-					json_object_put(jsonDescription);
 				}
 			}
 			else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -2607,6 +3251,19 @@ void setDefaultValue(uint8_t gun_index, uint8_t system_mode)
 				refreshStartTimer(&startTime[gun_index][TMR_IDX_PLUGIN]);
 			}
 
+			// Clean all CDFA value before start a session
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE = 0;
+			memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP));
+
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS = 0;
+			memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES));
+
 			break;
 		case SYS_MODE_AUTHORIZING:
 
@@ -2639,8 +3296,27 @@ void setDefaultValue(uint8_t gun_index, uint8_t system_mode)
 				refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_INFO]);
 			}
 
+			// Clean all CDFA value before start a session
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_KWH_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_HOUR_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_HOUR_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_KWH_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_METER_VALUE = 0;
+			memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP));
+
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS = 0;
+			memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES));
+
 			break;
 		case SYS_MODE_CHARGING:
+
+			CaliforniaPricing.LcmRunningCost[gun_index].END_OF_SESSION_IDLE_PRICE = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_REAL_TIME_IN_SECONDS = 0;
+			CaliforniaPricing.LcmRunningCost[gun_index].GRACE_MINUTES_PERIOD_COUNTER = 0;
+			memset(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES, 0x00, ARRAY_SIZE(CaliforniaPricing.LcmRunningCost[gun_index].PREVIOUS_TIMESTAMP_FOR_GRACE_MINUTES));
+
 			break;
 		case SYS_MODE_TERMINATING:
 

+ 1 - 0
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h

@@ -321,6 +321,7 @@
 #define SESSION_FEE							4
 #define TOTAL_COST							5
 #define ACCOUNT_BALANCE						6
+#define PRICE_TEXT							7
 
 //=======================================
 // Currency type