소스 검색

2023-01-13/ Jerry Wang
[OCPP 1.6] confVersion 25->26
[OCPP 2.0.1] variableVersion 9->10
Action:
1. Add setting logic on AlignedDataCtrlr variables 'SendDuringIdle' and 'SignReadings'.
2. Add configuration key 'EnableAcCcs'.
3. Modify configuration key 'AuthDownloadlinkCertificate' setting logic.
4. Improve the saving meterValuesBuffer logic to let it always updates the last one when data is full.

File:
1. EVSE/Modularization/ocpp20/MessageHandler.c
--> Action 1-2
2. EVSE/Modularization/ocppfiles/MessageHandler.c
--> Action 2-4
3. EVSE/Modularization/ocppfiles/MessageHandler.h
--> Action 2
4. EVSE/Projects/define.h
--> Action 2

Jerry Wang 2 년 전
부모
커밋
f4a62223fd

+ 68 - 1
EVSE/Modularization/ocpp20/MessageHandler.c

@@ -812,7 +812,7 @@ static int localversion=0;
 //===============================
 // Variable Version
 //===============================
-static int variableVersion=9;
+static int variableVersion=10;
 
 //===============================
 // OCPP sign variable
@@ -2807,6 +2807,14 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variableAttribute[0].value, "15");
 		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout]);
 
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].component.name, "OCPPCommCtrlr");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variable.name, "EnableAcCcs");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variableAttribute[0].value, "false");
+		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs]);
+
 		/* ReservationCtrlr Required item */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].component.name, "ReservationCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variable.name, "Enabled");
@@ -3514,6 +3522,9 @@ int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].component.name, "OCPPCommCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variable.name, "AuthorizeTimeout");
 
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].component.name, "OCPPCommCtrlr");
+		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_EnableAcCcs].variable.name, "EnableAcCcs");
+
 		/* ReservationCtrlr Required item */
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].component.name, "ReservationCtrlr");
 		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variable.name, "Enabled");
@@ -19330,6 +19341,7 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 						   (strlen((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance) != NULL):TRUE))
 						{
 							isUnknownComponent = FALSE;
+							strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
 							//DEBUG_INFO("Checking variable...[%s][%s], dataType: %s\n",ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name, ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.name, ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.dataType);
 
 							if(strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.dataType,DataEnumTypeStr[DataEnumType_decimal]) == 0)
@@ -19534,6 +19546,24 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 								}
 							}
 
+							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "EnableAcCcs") != NULL))
+							{
+								char tmp[ARRAY_SIZE(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)];
+
+								for(int tmpidx=0;tmpidx<ARRAY_SIZE(tmp);tmpidx++)
+									tmp[tmpidx] = tolower(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue[tmpidx]);
+								if((strstr((char*)tmp, "true") != NULL) || (strstr((char*)tmp, "false") != NULL))
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue,(strstr((char*)tmp, "true") != NULL)? "true" : "false");
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
+								}
+								else
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Rejected]);
+									break;
+								}
+							}
+
 							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "SecurityCtrlr") != NULL) &&
 							   ((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "SecurityProfile") != NULL) || (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "BasicAuthPassword") != NULL)))
 							{
@@ -19552,6 +19582,42 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
 							}
 
+							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "AlignedDataCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "SendDuringIdle") != NULL))
+							{
+								char tmp[ARRAY_SIZE(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)];
+
+								for(int tmpidx=0;tmpidx<ARRAY_SIZE(tmp);tmpidx++)
+									tmp[tmpidx] = tolower(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue[tmpidx]);
+								if((strstr((char*)tmp, "true") != NULL) || (strstr((char*)tmp, "false") != NULL))
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue,(strstr((char*)tmp, "true") != NULL)? "true" : "false");
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
+								}
+								else
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Rejected]);
+									break;
+								}
+							}
+
+							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "AlignedDataCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "SignReadings") != NULL))
+							{
+								char tmp[ARRAY_SIZE(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)];
+
+								for(int tmpidx=0;tmpidx<ARRAY_SIZE(tmp);tmpidx++)
+									tmp[tmpidx] = tolower(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue[tmpidx]);
+								if((strstr((char*)tmp, "true") != NULL) || (strstr((char*)tmp, "false") != NULL))
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue,(strstr((char*)tmp, "true") != NULL)? "true" : "false");
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
+								}
+								else
+								{
+									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Rejected]);
+									break;
+								}
+							}
+
 							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "SampledDataCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "TxUpdatedInterval") != NULL))
 							{
 								if((0 < atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)) && (atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < (int)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.minLimit) )
@@ -19609,6 +19675,7 @@ int handleSetVariablesRequest(char *uuid, char *payload)
 						}
 						else
 						{
+							// When there is no matched variable, check the component name again
 							if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name) != NULL)
 							{
 								isUnknownComponent = FALSE;

+ 81 - 3
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -483,6 +483,26 @@ int meterValueBufferInsert(uint8_t gun_index, ReadingContext dataType, uint32_t
 	return result;
 }
 
+int meterValueBufferReplace(int bufferIdx, uint8_t gun_index, ReadingContext dataType, uint32_t transactionId, char *meterValue)
+{
+	int result = PASS;
+	char sqlCmd[8192];
+	char *errMsg = 0;
+
+	sprintf(sqlCmd, "replace into meterValuesBuffer(idx, occurDatetime, gun_index, transactionId, ReadingContext, meterValue) values('%d', CURRENT_TIMESTAMP, '%d', '%d','%d','%s')", bufferIdx
+																																												   , gun_index
+																																												   , transactionId
+																																												   , (dataType==ReadingContext_Sample_Periodic?0:1)
+																																												   , meterValue);
+	if (sqlite3_exec(db, sqlCmd, 0, 0, &errMsg) != SQLITE_OK)
+	{
+		result = FAIL;
+		DEBUG_WARN( "Insert meter value record error message: %s\n", errMsg);
+	}
+
+	return result;
+}
+
 int meterValueBufferQuery(uint8_t gun_index, json_object *MeterValues)
 {
 	int result = PASS;
@@ -8858,7 +8878,10 @@ int sendMeterValuesRequest(int gun_index, ReadingContext dataType)
 			{
 				json_object_object_add(MeterValueBuffer, "timestamp", json_object_new_string((char*)ShmOCPP16Data->MeterValues[gun_index].MeterValue[idxMeter].TimeStamp));
 				json_object_object_add(MeterValueBuffer, "sampledValue", sampledValuesBuffer);
-				if(meterValueBufferDataQuantity(gun_index, dataType) < 200) meterValueBufferInsert(gun_index, dataType, ShmOCPP16Data->MeterValues[gun_index].TransactionId, (char*)json_object_to_json_string_ext(MeterValueBuffer, JSON_C_TO_STRING_PLAIN));
+				if(meterValueBufferDataQuantity(gun_index, dataType) < 200)
+					meterValueBufferInsert(gun_index, dataType, ShmOCPP16Data->MeterValues[gun_index].TransactionId, (char*)json_object_to_json_string_ext(MeterValueBuffer, JSON_C_TO_STRING_PLAIN));
+				else
+					meterValueBufferReplace(200, gun_index, dataType, ShmOCPP16Data->MeterValues[gun_index].TransactionId, (char*)json_object_to_json_string_ext(MeterValueBuffer, JSON_C_TO_STRING_PLAIN));
 				json_object_put(MeterValueBuffer);
 			}
 			else
@@ -17539,7 +17562,7 @@ int initialConfigurationTable(void)
 	FILE *fp;
 	FILE *outfile;
 	char str[512]={0};
-	int	confVersion = 25;
+	int	confVersion = 26;
 
 	DEBUG_INFO("initialConfigurationTable...version: %d\n", confVersion);
 	//start_t = clock();
@@ -18046,6 +18069,13 @@ int initialConfigurationTable(void)
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","AuthorizeTimeout", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData);
 
+		// Enable AC charger CCS function
+		ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemAccessibility = 1;
+		strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemName, "EnableAcCcs");
+		sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData, "FALSE");
+
+		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","EnableAcCcs", "false", ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData);
+
 		//* Local Auth List Management Profile*/
 		#if 0
 			//For OCTT Test Case
@@ -18540,6 +18570,12 @@ int initialConfigurationTable(void)
 					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData, "%s", valuestr);
 				}
 
+				if(strcmp(keystr, "EnableAcCcs") == 0)
+				{
+					ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
+					sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData, "%s", valuestr);
+				}
+
 				if(strcmp(keystr, "LocalAuthListEnabled") == 0)
 				{
 					ShmOCPP16Data->ConfigurationTable.LocalAuthListManagementProfile[LocalAuthListEnabled].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
@@ -19210,6 +19246,16 @@ void StoreConfigurationTable(void)
 
 	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","AuthorizeTimeout", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData);
 
+	// EnableAcCcs
+	/*
+	ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemAccessibility = 1;
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemName, "EnableAcCcs");
+	strcpy((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData, "TRUE" );
+	*/
+
+	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","EnableAcCcs", "false", (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData);
+
+
 	//* Local Auth List Management Profile*/
 	//LocalAuthListEnabled
 	/*
@@ -20442,6 +20488,24 @@ void getKeyValue(char *keyReq)
 			  isKnowKey = TRUE;
 		  }
 
+		  if(isEmpty ||  strcmp(keyReq, "EnableAcCcs") == 0 )
+		  {
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.Key[GetConfiguration_EnableAcCcs].Item, "EnableAcCcs");
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_EnableAcCcs].Key, "EnableAcCcs");
+
+			  if(ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemAccessibility == 1)
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_EnableAcCcs].ReadOnly, "0"/*"FALSE"*/);
+			  }
+			  else
+			  {
+				  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_EnableAcCcs].ReadOnly, "1"/*"TRUE"*/);
+			  }
+
+			  strcpy((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_EnableAcCcs].Value, (const char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData );
+			  isKnowKey = TRUE;
+		  }
+
 #if 1
 	      if(isEmpty ||  strcmp(keyReq, "LocalAuthListEnabled") == 0 )
 	      {
@@ -21871,7 +21935,7 @@ int setKeyValue(char *key, char *value)
 		if(ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthDownloadlinkCertificate].ItemAccessibility == 1)
 		{
 			strcpy(str, (const char*)value);
-			sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthDownloadlinkCertificate].ItemData, "%s", str );
+			sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthDownloadlinkCertificate].ItemData, "%s", (strcmp(str, "true")==0) ?"TRUE":"FALSE" );
 			isSuccess = ConfigurationStatus_Accepted;
 		}
 		else
@@ -21929,6 +21993,20 @@ int setKeyValue(char *key, char *value)
 		}
 	}
 
+	if(strcmp(key, "EnableAcCcs") == 0)
+	{
+		if(ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemAccessibility == 1)
+		{
+			strcpy(str, (const char*)value);
+			sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[EnableAcCcs].ItemData, "%s", (strcmp(str, "true")==0) ?"TRUE":"FALSE" );
+			isSuccess = ConfigurationStatus_Accepted;
+		}
+		else
+		{
+			isSuccess = ConfigurationStatus_Rejected;
+		}
+	}
+
 #if 0
     //For OCPP Test Case
     if(strcmp(key, "LocalAuthorizationListEnabled") == 0)

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

@@ -423,6 +423,7 @@ enum GetConfigurationKey {
 	GetConfiguration_AuthDownloadlinkCertificate,
 	GetConfiguration_RfidEndianType,
 	GetConfiguration_AuthorizeTimeout,
+	GetConfiguration_EnableAcCcs,
 	_GetConfiguration_CNT
 };
 

+ 2 - 0
EVSE/Projects/define.h

@@ -359,6 +359,7 @@ enum CoreProfile {
 	 AuthDownloadlinkCertificate,
 	 RfidEndianType,
 	 AuthorizeTimeout,
+	 EnableAcCcs,
 	 _CoreProfile_CNT
 };
 
@@ -5019,6 +5020,7 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_CharingProfileRefreshInterval,
     OCPPCommCtrlr_RfidEndianType,
 	OCPPCommCtrlr_AuthorizeTimeout,
+	OCPPCommCtrlr_EnableAcCcs,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
 	ReservationCtrlr_NonEvseSpecific,