瀏覽代碼

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,