Эх сурвалжийг харах

[Improve][Modularization][Module_OcppBackend]

2021.08.13 / Folus Wen

Actions:
1. Running cost compatible California pricing 1.1

Files:
1. As follow commit history

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

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 3 жил өмнө
parent
commit
f2af31a380

+ 305 - 8
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -2998,7 +2998,7 @@ void CheckSystemValue(void)
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
-							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+							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;
@@ -3055,7 +3055,7 @@ void CheckSystemValue(void)
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
-							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+							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;
@@ -3111,7 +3111,7 @@ void CheckSystemValue(void)
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
-							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+							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;
@@ -3159,7 +3159,7 @@ void CheckSystemValue(void)
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
-							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+							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;
@@ -3214,7 +3214,7 @@ void CheckSystemValue(void)
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
-							sprintf((char*)ShmOCPP16Data->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+							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;
@@ -8616,15 +8616,147 @@ int handleDataTransferRequest(char *uuid, char *payload)
 					{
 						if(ShmOCPP16Data->StartTransaction[idx].ResponseTransactionId == json_object_get_int(json_object_object_get(data, "txId")))
 						{
-							memset(&ShmOCPP16Data->Cost.RunningCost[idx], 0x00, sizeof(struct StrcutRunningFinalCost));
+							memset(&ShmOCPP16Data->Cost.RunningCost[idx], 0x00, sizeof(struct StrcutRunningCost));
 
 							ShmOCPP16Data->Cost.RunningCost[idx].txId = json_object_get_int(json_object_object_get(data, "txId"));
 
 							if(json_object_object_get(data, "description") != NULL)
 							{
+								// California pricing V1.0
+								DEBUG_INFO("California pricing V1.0\n");
 								DEBUG_INFO("description: %s\n", json_object_get_string(json_object_object_get(data, "description")));
 								sprintf((char*)ShmOCPP16Data->Cost.RunningCost[idx].description, "%s", json_object_get_string(json_object_object_get(data, "description")));
 							}
+							else
+							{
+								// California pricing V1.1
+								DEBUG_INFO("California pricing V1.1\n");
+								if(json_object_object_get(data, "timestamp") != NULL)
+								{
+									DEBUG_INFO("timestamp: %s\n", json_object_get_string(json_object_object_get(data, "timestamp")));
+									sprintf((char*)ShmOCPP16Data->Cost.RunningCost[idx].timestamp, "%s", json_object_get_string(json_object_object_get(data, "timestamp")));
+								}
+
+								if(json_object_object_get(data, "meterValue") != NULL)
+								{
+									DEBUG_INFO("meterValue: %d\n", json_object_get_int(json_object_object_get(data, "meterValue")));
+									ShmOCPP16Data->Cost.RunningCost[idx].meterValue = json_object_get_int(json_object_object_get(data, "meterValue"));
+								}
+
+								if(json_object_object_get(data, "cost") != NULL)
+								{
+									DEBUG_INFO("cost: %f\n", json_object_get_double(json_object_object_get(data, "cost")));
+									ShmOCPP16Data->Cost.RunningCost[idx].cost = json_object_get_double(json_object_object_get(data, "cost"));
+								}
+
+								if(json_object_object_get(data, "state") != NULL)
+								{
+									DEBUG_INFO("state: %s\n", json_object_get_string(json_object_object_get(data, "state")));
+									sprintf((char*)ShmOCPP16Data->Cost.RunningCost[idx].state, "%s", json_object_get_string(json_object_object_get(data, "state")));
+								}
+
+								if(json_object_object_get(data, "chargingPrice") != NULL)
+								{
+									if(json_object_object_get(json_object_object_get(data, "chargingPrice"), "kWhPrice") != NULL)
+									{
+										DEBUG_INFO("chargingPrice-kWhPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "kWhPrice")));
+										ShmOCPP16Data->Cost.RunningCost[idx].chargingPrice.kWhPrice = json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "kWhPrice"));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "chargingPrice"), "hourPrice") != NULL)
+									{
+										DEBUG_INFO("chargingPrice-hourPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "hourPrice")));
+										ShmOCPP16Data->Cost.RunningCost[idx].chargingPrice.hourPrice = json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "hourPrice"));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "chargingPrice"), "flatFee") != NULL)
+									{
+										DEBUG_INFO("chargingPrice-flatFee: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "flatFee")));
+										ShmOCPP16Data->Cost.RunningCost[idx].chargingPrice.flatFee = json_object_get_double(json_object_object_get(json_object_object_get(data, "chargingPrice"), "flatFee"));
+									}
+								}
+
+								if(json_object_object_get(data, "idlePrice") != NULL)
+								{
+									if(json_object_object_get(json_object_object_get(data, "idlePrice"), "graceMinutes") != NULL)
+									{
+										DEBUG_INFO("idlePrice-graceMinutes: %d\n", json_object_get_int(json_object_object_get(json_object_object_get(data, "idlePrice"), "graceMinutes")));
+										ShmOCPP16Data->Cost.RunningCost[idx].idlePrice.graceMinutes = json_object_get_int(json_object_object_get(json_object_object_get(data, "idlePrice"), "graceMinutes"));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "idlePrice"), "hourPrice") != NULL)
+									{
+										DEBUG_INFO("idlePrice-hourPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "idlePrice"), "hourPrice")));
+										ShmOCPP16Data->Cost.RunningCost[idx].idlePrice.hourPrice = json_object_get_double(json_object_object_get(json_object_object_get(data, "idlePrice"), "hourPrice"));
+									}
+								}
+
+								if(json_object_object_get(data, "nextPeriod") != NULL)
+								{
+									if(json_object_object_get(json_object_object_get(data, "nextPeriod"), "atTime") != NULL)
+									{
+										DEBUG_INFO("nextPeriod-atTime: %s\n", json_object_get_string(json_object_object_get(json_object_object_get(data, "nextPeriod"), "atTime")));
+										sprintf((char*)ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.atTime, "%s", json_object_get_string(json_object_object_get(json_object_object_get(data, "nextPeriod"), "atTime")));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice") != NULL)
+									{
+										if(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "kWhPrice") != NULL)
+										{
+											DEBUG_INFO("nextPeriod-chargingPrice-kWhPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "kWhPrice")));
+											ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.chargingPrice.kWhPrice = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "kWhPrice"));
+										}
+
+										if(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "hourPrice") != NULL)
+										{
+											DEBUG_INFO("nextPeriod-chargingPrice-hourPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "hourPrice")));
+											ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.chargingPrice.hourPrice = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "hourPrice"));
+										}
+
+										if(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "flatFee") != NULL)
+										{
+											DEBUG_INFO("nextPeriod-chargingPrice-flatFee: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "flatFee")));
+											ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.chargingPrice.flatFee = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "chargingPrice"), "flatFee"));
+										}
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice") != NULL)
+									{
+										if(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "graceMinutes") != NULL)
+										{
+											DEBUG_INFO("nextPeriod-idlePrice-graceMinutes: %d\n", json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "graceMinutes")));
+											ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.idlePrice.graceMinutes = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "graceMinutes"));
+										}
+
+										if(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "hourPrice") != NULL)
+										{
+											DEBUG_INFO("nextPeriod-idlePrice-hourPrice: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "hourPrice")));
+											ShmOCPP16Data->Cost.RunningCost[idx].nextPeriod.idlePrice.hourPrice = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(data, "nextPeriod"), "idlePrice"), "hourPrice"));
+										}
+									}
+								}
+
+								if(json_object_object_get(data, "triggerMeterValue") != NULL)
+								{
+									if(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atTime") != NULL)
+									{
+										DEBUG_INFO("triggerMeterValue-atTime: %s\n", json_object_get_string(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atTime")));
+										sprintf((char*)ShmOCPP16Data->Cost.RunningCost[idx].triggerMeterValue.atTime, "%s", json_object_get_string(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atTime")));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atEnergykWh") != NULL)
+									{
+										DEBUG_INFO("triggerMeterValue-atEnergykWh: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atEnergykWh")));
+										ShmOCPP16Data->Cost.RunningCost[idx].triggerMeterValue.atEnergykWh = json_object_get_double(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atEnergykWh"));
+									}
+
+									if(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atPowerkW") != NULL)
+									{
+										DEBUG_INFO("triggerMeterValue-atPowerkW: %f\n", json_object_get_double(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atPowerkW")));
+										ShmOCPP16Data->Cost.RunningCost[idx].triggerMeterValue.atPowerkW = json_object_get_double(json_object_object_get(json_object_object_get(data, "triggerMeterValue"), "atPowerkW"));
+									}
+								}
+							}
 						}
 					}
 				}
@@ -8654,7 +8786,7 @@ int handleDataTransferRequest(char *uuid, char *payload)
 					{
 						if(ShmOCPP16Data->StartTransaction[idx].ResponseTransactionId == json_object_get_int(json_object_object_get(data, "txId")))
 						{
-							memset(&ShmOCPP16Data->Cost.FinalCost[idx], 0x00, sizeof(struct StrcutRunningFinalCost));
+							memset(&ShmOCPP16Data->Cost.FinalCost[idx], 0x00, sizeof(struct StrcutFinalCost));
 
 							ShmOCPP16Data->Cost.FinalCost[idx].txId = json_object_get_int(json_object_object_get(data, "txId"));
 
@@ -12803,7 +12935,7 @@ int initialConfigurationTable(void)
 	char sstr[256]={0};
 	int c = 0;
 	char *loc;
-	int	confVersion = 3;
+	int	confVersion = 4;
 
 	DEBUG_INFO("initialConfigurationTable...version: %d\n", confVersion);
 	//start_t = clock();
@@ -13149,6 +13281,27 @@ int initialConfigurationTable(void)
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","CustomIdleFeeAfterStop", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData);
 
+		// TimeOffset
+		ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemAccessibility = 1;
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemName, "TimeOffset");
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData, "+00:00" );
+
+		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","TimeOffset", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData);
+
+		// NextTimeOffsetTransitionDateTime
+		ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemAccessibility = 1;
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemName, "NextTimeOffsetTransitionDateTime");
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData, " " );
+
+		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","NextTimeOffsetTransitionDateTime", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData);
+
+		// TimeOffsetNextTransition
+		ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemAccessibility = 1;
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemName, "TimeOffsetNextTransition");
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData, "+00:00" );
+
+		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","TimeOffsetNextTransition", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData);
+
 		// Configuration Version
 		ShmOCPP16Data->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemName, "ConfigurationVersion");
@@ -13553,6 +13706,24 @@ int initialConfigurationTable(void)
 					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData, "%s", valuestr);
 				}
 
+				if(strcmp(keystr, "TimeOffset") == 0)
+				{
+					ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
+					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData, "%s", valuestr);
+				}
+
+				if(strcmp(keystr, "NextTimeOffsetTransitionDateTime") == 0)
+				{
+					ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
+					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData, "%s", valuestr);
+				}
+
+				if(strcmp(keystr, "TimeOffsetNextTransition") == 0)
+				{
+					ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
+					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData, "%s", valuestr);
+				}
+
 				if(strcmp(keystr, "ConfigurationVersion") == 0)
 				{
 					ShmOCPP16Data->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
@@ -14012,6 +14183,33 @@ void StoreConfigurationTable(void)
 
 	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","CustomIdleFeeAfterStop", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData);
 
+	// TimeOffset
+	/*
+	ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemAccessibility = 1;
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemName, "TimeOffset");
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData, "FALSE" );
+	*/
+
+	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","TimeOffset", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData);
+
+	// NextTimeOffsetTransitionDateTime
+	/*
+	ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemAccessibility = 1;
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemName, "NextTimeOffsetTransitionDateTime");
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData, "FALSE" );
+	*/
+
+	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","NextTimeOffsetTransitionDateTime", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData);
+
+	// TimeOffsetNextTransition
+	/*
+	ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemAccessibility = 1;
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemName, "TimeOffsetNextTransition");
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData, "FALSE" );
+	*/
+
+	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","TimeOffsetNextTransition", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData);
+
 	// ConfigurationVersion
 	/*
 	ShmOCPP16Data->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = 1;
@@ -14845,6 +15043,60 @@ void getKeyValue(char *keyReq)
 			  isKnowKey = TRUE;
 		  }
 
+	      if(isEmpty ||  strcmp(keyReq, "TimeOffset") == 0 )
+		  {
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.Key[GetConfiguration_TimeOffset].Item, "TimeOffset");
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffset].Key, "TimeOffset");
+
+			  if(ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemAccessibility == 1)
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffset].ReadOnly, "0"/*"FALSE"*/);
+			  }
+			  else
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffset].ReadOnly, "1"/*"TRUE"*/);
+			  }
+
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffset].Value, (const char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData );
+			  isKnowKey = TRUE;
+		  }
+
+	      if(isEmpty ||  strcmp(keyReq, "NextTimeOffsetTransitionDateTime") == 0 )
+		  {
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.Key[GetConfiguration_NextTimeOffsetTransitionDateTime].Item, "NextTimeOffsetTransitionDateTime");
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_NextTimeOffsetTransitionDateTime].Key, "NextTimeOffsetTransitionDateTime");
+
+			  if(ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemAccessibility == 1)
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_NextTimeOffsetTransitionDateTime].ReadOnly, "0"/*"FALSE"*/);
+			  }
+			  else
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_NextTimeOffsetTransitionDateTime].ReadOnly, "1"/*"TRUE"*/);
+			  }
+
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_NextTimeOffsetTransitionDateTime].Value, (const char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData );
+			  isKnowKey = TRUE;
+		  }
+
+	      if(isEmpty ||  strcmp(keyReq, "TimeOffsetNextTransition") == 0 )
+		  {
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.Key[GetConfiguration_TimeOffsetNextTransition].Item, "TimeOffsetNextTransition");
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffsetNextTransition].Key, "TimeOffsetNextTransition");
+
+			  if(ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemAccessibility == 1)
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffsetNextTransition].ReadOnly, "0"/*"FALSE"*/);
+			  }
+			  else
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffsetNextTransition].ReadOnly, "1"/*"TRUE"*/);
+			  }
+
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_TimeOffsetNextTransition].Value, (const char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData );
+			  isKnowKey = TRUE;
+		  }
+
 	      if(isEmpty ||  strcmp(keyReq, "ConfigurationVersion") == 0 )
 		  {
 			  strcpy((char *)ShmOCPP16Data->GetConfiguration.Key[GetConfiguration_ConfigurationVersion].Item, "ConfigurationVersion");
@@ -15950,6 +16202,51 @@ int setKeyValue(char *key, char *value)
 	   }
 
     }
+
+    if(strcmp(key, "TimeOffset") == 0)
+    {
+    	if(ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemAccessibility == 1)
+		{
+    		strcpy(str, (const char*)value);
+    		sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffset].ItemData, "%s", str);
+    		isSuccess = ConfigurationStatus_Accepted;
+		}
+		else
+	   {
+		isSuccess = ConfigurationStatus_Rejected;
+	   }
+
+    }
+
+    if(strcmp(key, "NextTimeOffsetTransitionDateTime") == 0)
+    {
+    	if(ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemAccessibility == 1)
+		{
+    		strcpy(str, (const char*)value);
+    		sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[NextTimeOffsetTransitionDateTime].ItemData, "%s", str);
+			isSuccess = ConfigurationStatus_Accepted;
+		}
+		else
+	   {
+		isSuccess = ConfigurationStatus_Rejected;
+	   }
+
+    }
+
+    if(strcmp(key, "TimeOffsetNextTransition") == 0)
+    {
+    	if(ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemAccessibility == 1)
+		{
+    		strcpy(str, (const char*)value);
+    		sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[TimeOffsetNextTransition].ItemData, "%s", str);
+			isSuccess = ConfigurationStatus_Accepted;
+		}
+		else
+	   {
+		isSuccess = ConfigurationStatus_Rejected;
+	   }
+
+    }
 #if 0
     //For OCPP Test Case
     if(strcmp(key, "LocalAuthorizationListEnabled") == 0)

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

@@ -392,6 +392,9 @@ enum GetConfigurationKey {
 	GetConfiguration_DefaultPrice,
 	GetConfiguration_CustomDisplayCostAndPrice,
 	GetConfiguration_CustomIdleFeeAfterStop,
+	GetConfiguration_TimeOffset,
+	GetConfiguration_NextTimeOffsetTransitionDateTime,
+	GetConfiguration_TimeOffsetNextTransition,
 	GetConfiguration_LocalAuthListEnabled,
 	GetConfiguration_LocalAuthListMaxLength,
 	GetConfiguration_SendLocalListMaxLength,

+ 50 - 3
EVSE/Projects/define.h

@@ -293,6 +293,9 @@ enum CoreProfile {
      DefaultPrice,
      CustomDisplayCostAndPrice,
      CustomIdleFeeAfterStop,
+	 TimeOffset,
+	 NextTimeOffsetTransitionDateTime,
+	 TimeOffsetNextTransition,
      ConfigurationVersion,
 	 _CoreProfile_CNT
 };
@@ -4292,7 +4295,51 @@ struct StrcutSetUserPrice
     unsigned char   price[256];
 };
 
-struct StrcutRunningFinalCost
+struct ChargingPrice
+{
+	float kWhPrice;									// Price per kWh
+	float hourPrice;								// Price per hour of charging
+	float flatFee;									// Flat fee for (part of) charging session
+};
+
+struct IdlePrice
+{
+	unsigned int graceMinutes;						// Grace period in minutes before idle time is charged
+	float hourPrice;								// Price per hour while idle
+};
+
+struct NextPeriod
+{
+	unsigned char atTime[36];						// Time when these prices become active
+	struct ChargingPrice chargingPrice;				// Price components while charging
+	struct IdlePrice idlePrice;						// Price components while idle. Optional if no idle fee charged.
+};
+
+struct Triggers
+{
+	unsigned char atTime[36];						// Time when these prices become active
+	float atEnergykWh;								// Consumed energy amount in kWh upon which a meter value must be sent
+	float atPowerkW;								// Power threshold in kW when meter value must be sent when crossing in downward or upward direction. Can either
+													// be used to trigger a meter value when vehicle stops charging	or when vehicle charges at a high power that requires a
+													// different tariff.
+													// It is recommended to implement a hysteresis around this value to avoid repetitive triggers when the power fluctuates around this level.
+};
+
+struct StrcutRunningCost
+{
+    int             		txId;					// Transaction to which this applies
+    unsigned char   		timestamp[36];			// Timestamp of the meter value upon which this cost is based
+    unsigned int			meterValue;				// Meter value (Wh) upon which this cost is based
+    float					cost;					// Calculated total running cost
+    unsigned char			state[16];				// "Charging" or "Idle"
+    struct ChargingPrice	chargingPrice;			// Price components while charging
+    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
+};
+
+struct StrcutFinalCost
 {
     int             txId;
     unsigned char   description[256];
@@ -4301,8 +4348,8 @@ struct StrcutRunningFinalCost
 struct StructCost
 {
     struct StrcutSetUserPrice       SetUserPrice;
-    struct StrcutRunningFinalCost   RunningCost[CONNECTOR_QUANTITY];
-    struct StrcutRunningFinalCost   FinalCost[CONNECTOR_QUANTITY];
+    struct StrcutRunningCost   		RunningCost[CONNECTOR_QUANTITY];
+    struct StrcutFinalCost   		FinalCost[CONNECTOR_QUANTITY];
 };
 
 struct CertificateHashDataType