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

2022-02-18/Jerry Wang
Action:
1. Add item 'VEMData' in DataTransfer message [ID_ReaderStatus] & [ID_GetTxUserInfo].
2. Modify sending StatusNotification minimum interval to 1sec for reporting changed status.
3. Modify setChargingProfile logic that check chargingProfileId and stackLevel is same as the local profile for replacement.

File:
1. EVSE/Modularization/ocppfiles/MessageHandler.c
--> Action 1,2,3
2. EVSE/Modularization/ocppph/MessageHandler.c
--> Action 1,2,3
3. define.h
--> Action 1

Jerry Wang 3 жил өмнө
parent
commit
5cfa6442b8

+ 96 - 22
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -1398,12 +1398,13 @@ void reportReaderStatus(int gun_index)
 	#endif
 	sprintf((char*)ShmOCPP16Data->DataTransfer[0].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 	sprintf((char*)ShmOCPP16Data->DataTransfer[0].MessageId,"%s","ID_ReaderStatus");
-	sprintf((char*)ShmOCPP16Data->DataTransfer[0].Data, "{\\\"connectorId\\\":%d,\\\"readerStatus\\\":%d,\\\"timestamp\\\":\\\"%s\\\",\\\"SerialNo\\\":\\\"%s\\\",\\\"creditNo\\\":\\\"%s\\\"}",
+	sprintf((char*)ShmOCPP16Data->DataTransfer[0].Data, "{\\\"connectorId\\\":%d,\\\"readerStatus\\\":%d,\\\"timestamp\\\":\\\"%s\\\",\\\"SerialNo\\\":\\\"%s\\\",\\\"creditNo\\\":\\\"%s\\\",\\\"VEMData\\\":\\\"%s\\\"}",
 			(gun_index+1),
 			ShmOCPP16Data->TcciCustomData.ReaderStatus[gun_index].readerStatus,
 			buf,
 			ShmOCPP16Data->TcciCustomData.SerialNo[gun_index],
-			ShmOCPP16Data->TcciCustomData.ReaderStatus[gun_index].creditNo);
+			ShmOCPP16Data->TcciCustomData.ReaderStatus[gun_index].creditNo,
+			ShmOCPP16Data->TcciCustomData.VEMData[gun_index]);
 
 	ShmOCPP16Data->CsMsg.bits[0].DataTransferReq = 1;
 }
@@ -5032,7 +5033,7 @@ void CheckSystemValue(void)
 			}// END
 		}
 
-		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 5) &&
+		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 1) &&
 			(
 				(cpinitateMsg.bits[gun_index].StatusNotificationReq == 1) || (cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq == 1) ||
 				((strcmp((const char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[StatusNotificationPeriodically].ItemData, "TRUE") == 0) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= atoi((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[StatusNotificationInterval].ItemData)))
@@ -11094,6 +11095,7 @@ int handleDataTransferRequest(char *uuid, char *payload)
 							json_object_object_add(responsedata, "ConnectorId", json_object_new_int(gun_index+1));
 							json_object_object_add(responsedata, "SerialNo", json_object_new_string((char*)ShmOCPP16Data->TcciCustomData.SerialNo[gun_index]));
 							json_object_object_add(responsedata, "StartTime", json_object_new_string((char*)ShmOCPP16Data->StartTransaction[gun_index].Timestamp));
+							json_object_object_add(responsedata, "VEMData", json_object_new_string((char*)ShmOCPP16Data->TcciCustomData.VEMData[gun_index]));
 							json_object_object_add(response, "data", json_object_new_string(json_object_to_json_string_ext(responsedata, JSON_C_TO_STRING_PLAIN)));
 						}
 						else
@@ -13562,12 +13564,14 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	int result = FAIL;
 	struct StructSetChargingProfile SetProfileReq = {0};
 	int tempchargingProfileIdInt;
+	int tempstackLevelInt;
 	int chargingSchedulePeriodCount = 0;
 	char comfirmstr[20]={0};
 	char tempfile[] = "/Storage/OCPP/SetChargingProfiletemp.json";
 	char rmFileCmd[128]={0};
 
 	int profileQuantity = 0;
+	int isReplaceable = FALSE;
 	json_object *SetChargingProfile;
 
 	DEBUG_INFO("handleSetChargingProfileRequest\n");
@@ -13721,7 +13725,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	if(strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[ChargePointMaxProfile]) == 0)
 	{
 		FILE *fp;
-		char dataLine[4096]={0};
 		DEBUG_INFO("Profile purpose is ChargePointMaxProfile.\n");
 
 		if(SetProfileReq.ConnectorId != 0)
@@ -13739,11 +13742,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 		else
 		{
-			while(fscanf(fp, "%s", dataLine) != EOF)
+			char *line = NULL;
+			size_t len = 0;
+			while(getline(&line, &len, fp) != -1)
 			{
-				if(strstr(dataLine, "chargingProfileId")!= NULL)
+				json_object *obj = NULL;
+
+				obj = json_tokener_parse(line);
+				if(is_error(obj))
 				{
-					profileQuantity += 1;
+					DEBUG_ERROR("Parse txProfile from file error.\n");
+				}
+				else
+				{
+					if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+					   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+					{
+						profileQuantity += 1;
+					}
+					else
+						isReplaceable = TRUE;
 				}
 			}
 		}
@@ -13752,7 +13770,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	else if(strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[TxDefaultProfile]) == 0)
 	{
 		FILE *fp;
-		char dataLine[4096]={0};
 		char filename[128]={0};
 		int tmpProfileQuantity;
 		DEBUG_INFO("Profile purpose is TxDefaultProfile.\n");
@@ -13780,11 +13797,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 				}
 				else
 				{
-					while(fscanf(fp, "%s", dataLine) != EOF)
+					char *line = NULL;
+					size_t len = 0;
+					while(getline(&line, &len, fp) != -1)
 					{
-						if(strstr(dataLine, "chargingProfileId")!= NULL)
+						json_object *obj = NULL;
+
+						obj = json_tokener_parse(line);
+						if(is_error(obj))
 						{
-							tmpProfileQuantity += 1;
+							DEBUG_ERROR("Parse txProfile from file error.\n");
+						}
+						else
+						{
+							if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+							   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+							{
+								tmpProfileQuantity += 1;
+							}
+							else
+								isReplaceable = TRUE;
 						}
 					}
 				}
@@ -13806,11 +13838,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			}
 			else
 			{
-				while(fscanf(fp, "%s", dataLine) != EOF)
+				char *line = NULL;
+				size_t len = 0;
+				while(getline(&line, &len, fp) != -1)
 				{
-					if(strstr(dataLine, "chargingProfileId")!= NULL)
+					json_object *obj = NULL;
+
+					obj = json_tokener_parse(line);
+					if(is_error(obj))
 					{
-						profileQuantity += 1;
+						DEBUG_ERROR("Parse txProfile from file error.\n");
+					}
+					else
+					{
+						if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+						   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+						{
+							profileQuantity += 1;
+						}
+						else
+							isReplaceable = TRUE;
 					}
 				}
 			}
@@ -13821,7 +13868,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	{
 		int isMatchTransactiodId= FALSE;
 		FILE *fp;
-		char dataLine[4096]={0};
 		char filename[128]={0};
 		DEBUG_INFO("Profile purposeStr is TxProfile.\n");
 
@@ -13987,13 +14033,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 		else
 		{
-			//Check Charging Profile Count
-			while(fscanf(fp, "%s", dataLine) != EOF)
+			char *line = NULL;
+			size_t len = 0;
+			while(getline(&line, &len, fp) != -1)
 			{
-				//DEBUG_INFO("word=%s\n",word);
-				if(strstr(dataLine, "chargingProfileId")!= NULL)
+				json_object *obj = NULL;
+
+				obj = json_tokener_parse(line);
+				if(is_error(obj))
 				{
-					profileQuantity += 1;
+					DEBUG_ERROR("Parse txProfile from file error.\n");
+				}
+				else
+				{
+					if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+					   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+					{
+						profileQuantity += 1;
+					}
+					else
+						isReplaceable = TRUE;
 				}
 			}
 		}
@@ -14086,9 +14145,9 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 
 		DEBUG_INFO("All purpose profile quantity: %d\n", profileQuantity);
-		if(profileQuantity > atoi((const char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData))
+		if((profileQuantity >= atoi((const char *)ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData)) && (isReplaceable != TRUE))
 		{
-			sprintf(comfirmstr, "%s", ChargingProfileStatusStr[ChargingProfileStatus_Rejected] );
+			sprintf(comfirmstr, "%s", ChargingProfileStatusStr[ChargingProfileStatus_Rejected]);
 			DEBUG_WARN("Total profile quantify is over installed limit %s.\n", ShmOCPP16Data->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData);
 			goto end;
 		}
@@ -14161,6 +14220,11 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 							{
 								tempchargingProfileIdInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId"));
 							}
+
+							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel") != NULL)
+							{
+								tempstackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel"));
+							}
 						}
 					}
 					json_object_put(tmpChargingProfile);
@@ -14175,6 +14239,16 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 							ChargingProfileAdded = TRUE;
 						}
 					}
+					else if(tempstackLevelInt == SetProfileReq.ChargingProfile.StackLevel)
+					{
+						if(ChargingProfileAdded == FALSE)
+						{
+							if((strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[TxDefaultProfile]) == 0) && (SetProfileReq.ConnectorId==0))
+								json_object_object_add(SetChargingProfile, "connectorId", json_object_new_int(idxCon));
+							fprintf(outfile,"%s\n",json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));
+							ChargingProfileAdded = TRUE;
+						}
+					}
 					else
 					{
 						fprintf(outfile,"%s\n",dataLine);

+ 95 - 21
EVSE/Modularization/ocppph/MessageHandler.c

@@ -905,12 +905,13 @@ void reportReaderStatus(int gun_index)
 	#endif
 	sprintf((char*)ShmOCPP16DataPH->DataTransfer[0].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 	sprintf((char*)ShmOCPP16DataPH->DataTransfer[0].MessageId,"%s","ID_ReaderStatus");
-	sprintf((char*)ShmOCPP16DataPH->DataTransfer[0].Data, "{\\\"connectorId\\\":%d,\\\"readerStatus\\\":%d,\\\"timestamp\\\":\\\"%s\\\",\\\"SerialNo\\\":\\\"%s\\\",\\\"creditNo\\\":\\\"%s\\\"}",
+	sprintf((char*)ShmOCPP16DataPH->DataTransfer[0].Data, "{\\\"connectorId\\\":%d,\\\"readerStatus\\\":%d,\\\"timestamp\\\":\\\"%s\\\",\\\"SerialNo\\\":\\\"%s\\\",\\\"creditNo\\\":\\\"%s\\\",\\\"VEMData\\\":\\\"%s\\\"}",
 			(gun_index+1),
 			ShmOCPP16DataPH->TcciCustomData.ReaderStatus[gun_index].readerStatus,
 			buf,
 			ShmOCPP16DataPH->TcciCustomData.SerialNo[gun_index],
-			ShmOCPP16DataPH->TcciCustomData.ReaderStatus[gun_index].creditNo);
+			ShmOCPP16DataPH->TcciCustomData.ReaderStatus[gun_index].creditNo,
+			ShmOCPP16Data->TcciCustomData.VEMData[gun_index]);
 
 	ShmOCPP16DataPH->CsMsg.bits[0].DataTransferReq = 1;
 }
@@ -4552,7 +4553,7 @@ void CheckSystemValue(void)
 			}// END
 		}
 
-		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 5) &&
+		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 1) &&
 			(
 				(cpinitateMsg.bits[gun_index].StatusNotificationReq == 1) || (cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq == 1) ||
 				((strcmp((const char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[StatusNotificationPeriodically].ItemData, "TRUE") == 0) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= atoi((char*)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[StatusNotificationInterval].ItemData)))
@@ -10588,6 +10589,7 @@ int handleDataTransferRequest(char *uuid, char *payload)
 								json_object_object_add(responsedata, "ConnectorId", json_object_new_int(gun_index+1));
 								json_object_object_add(responsedata, "SerialNo", json_object_new_string((char*)ShmOCPP16DataPH->TcciCustomData.SerialNo[gun_index]));
 								json_object_object_add(responsedata, "StartTime", json_object_new_string((char*)ShmOCPP16DataPH->StartTransaction[gun_index].Timestamp));
+								json_object_object_add(responsedata, "VEMData", json_object_new_string((char*)ShmOCPP16Data->TcciCustomData.VEMData[gun_index]));
 								json_object_object_add(response, "data", json_object_new_string(json_object_to_json_string_ext(responsedata, JSON_C_TO_STRING_PLAIN)));
 							}
 							else
@@ -13068,12 +13070,14 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	int result = FAIL;
 	struct StructSetChargingProfile SetProfileReq = {0};
 	int tempchargingProfileIdInt;
+	int tempstackLevelInt;
 	int chargingSchedulePeriodCount = 0;
 	char comfirmstr[20]={0};
 	char tempfile[] = "/Storage/OCPP_PH/SetChargingProfiletemp.json";
 	char rmFileCmd[128]={0};
 
 	int profileQuantity = 0;
+	int isReplaceable = FALSE;
 	json_object *SetChargingProfile;
 
 	DEBUG_INFO("handleSetChargingProfileRequest\n");
@@ -13227,7 +13231,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	if(strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[ChargePointMaxProfile]) == 0)
 	{
 		FILE *fp;
-		char dataLine[4096]={0};
 		DEBUG_INFO("Profile purpose is ChargePointMaxProfile.\n");
 
 		if(SetProfileReq.ConnectorId != 0)
@@ -13244,11 +13247,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 		else
 		{
-			while(fscanf(fp, "%s", dataLine) != EOF)
+			char *line = NULL;
+			size_t len = 0;
+			while(getline(&line, &len, fp) != -1)
 			{
-				if(strstr(dataLine, "chargingProfileId")!= NULL)
+				json_object *obj = NULL;
+
+				obj = json_tokener_parse(line);
+				if(is_error(obj))
 				{
-					profileQuantity += 1;
+					DEBUG_ERROR("Parse txProfile from file error.\n");
+				}
+				else
+				{
+					if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+					   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+					{
+						profileQuantity += 1;
+					}
+					else
+						isReplaceable = TRUE;
 				}
 			}
 		}
@@ -13257,7 +13275,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	else if(strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[TxDefaultProfile]) == 0)
 	{
 		FILE *fp;
-		char dataLine[4096]={0};
 		char filename[128]={0};
 		int tmpProfileQuantity;
 		DEBUG_INFO("Profile purpose is TxDefaultProfile.\n");
@@ -13284,11 +13301,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 				}
 				else
 				{
-					while(fscanf(fp, "%s", dataLine) != EOF)
+					char *line = NULL;
+					size_t len = 0;
+					while(getline(&line, &len, fp) != -1)
 					{
-						if(strstr(dataLine, "chargingProfileId")!= NULL)
+						json_object *obj = NULL;
+
+						obj = json_tokener_parse(line);
+						if(is_error(obj))
 						{
-							tmpProfileQuantity += 1;
+							DEBUG_ERROR("Parse txProfile from file error.\n");
+						}
+						else
+						{
+							if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+							   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+							{
+								tmpProfileQuantity += 1;
+							}
+							else
+								isReplaceable = TRUE;
 						}
 					}
 				}
@@ -13310,11 +13342,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			}
 			else
 			{
-				while(fscanf(fp, "%s", dataLine) != EOF)
+				char *line = NULL;
+				size_t len = 0;
+				while(getline(&line, &len, fp) != -1)
 				{
-					if(strstr(dataLine, "chargingProfileId")!= NULL)
+					json_object *obj = NULL;
+
+					obj = json_tokener_parse(line);
+					if(is_error(obj))
 					{
-						profileQuantity += 1;
+						DEBUG_ERROR("Parse txProfile from file error.\n");
+					}
+					else
+					{
+						if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+						   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+						{
+							profileQuantity += 1;
+						}
+						else
+							isReplaceable = TRUE;
 					}
 				}
 			}
@@ -13325,7 +13372,6 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 	{
 		int isMatchTransactiodId= FALSE;
 		FILE *fp;
-		char dataLine[4096]={0};
 		char filename[128]={0};
 		DEBUG_INFO("Profile purposeStr is TxProfile.\n");
 
@@ -13488,13 +13534,26 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 		else
 		{
-			//Check Charging Profile Count
-			while(fscanf(fp, "%s", dataLine) != EOF)
+			char *line = NULL;
+			size_t len = 0;
+			while(getline(&line, &len, fp) != -1)
 			{
-				//DEBUG_INFO("word=%s\n",word);
-				if(strstr(dataLine, "chargingProfileId")!= NULL)
+				json_object *obj = NULL;
+
+				obj = json_tokener_parse(line);
+				if(is_error(obj))
 				{
-					profileQuantity += 1;
+					DEBUG_ERROR("Parse txProfile from file error.\n");
+				}
+				else
+				{
+					if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != SetProfileReq.ChargingProfile.ChargingProfileId) &&
+					   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) != SetProfileReq.ChargingProfile.StackLevel))
+					{
+						profileQuantity += 1;
+					}
+					else
+						isReplaceable = TRUE;
 				}
 			}
 		}
@@ -13586,7 +13645,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 		}
 
 		DEBUG_INFO("All purpose profile quantity: %d\n", profileQuantity);
-		if(profileQuantity > atoi((const char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData))
+		if((profileQuantity > atoi((const char *)ShmOCPP16DataPH->ConfigurationTable.SmartChargingProfile[MaxChargingProfilesInstalled].ItemData)) && (isReplaceable != TRUE))
 		{
 			sprintf(comfirmstr, "%s", ChargingProfileStatusStr[ChargingProfileStatus_Rejected] );
 			goto end;
@@ -13660,6 +13719,11 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 							{
 								tempchargingProfileIdInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId"));
 							}
+
+							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel") != NULL)
+							{
+								tempstackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel"));
+							}
 						}
 					}
 					json_object_put(tmpChargingProfile);
@@ -13674,6 +13738,16 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 							ChargingProfileAdded = TRUE;
 						}
 					}
+					else if(tempstackLevelInt == SetProfileReq.ChargingProfile.StackLevel)
+					{
+						if(ChargingProfileAdded == FALSE)
+						{
+							if((strcmp((char*)SetProfileReq.ChargingProfile.ChargingProfilePurpose, ChargingProfilePurposeTypeStr[TxDefaultProfile]) == 0) && (SetProfileReq.ConnectorId==0))
+								json_object_object_add(SetChargingProfile, "connectorId", json_object_new_int(idxCon));
+							fprintf(outfile,"%s\n",json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));
+							ChargingProfileAdded = TRUE;
+						}
+					}
 					else
 					{
 						fprintf(outfile,"%s\n",dataLine);

+ 1 - 0
EVSE/Projects/define.h

@@ -4613,6 +4613,7 @@ struct StructTcciCustomData
     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;