Browse Source

[Improve][Modularization][Module_OcppBackend / Module_OcppBackendPH]

2022.05.13 / Folus Wen

Actions:
1. DataTransfer message id "ConnectorUnplugged" put to queue pool.
2. sentqueue() mapping logic change parsing method to JSON-C library.

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 2 years ago
parent
commit
ae90d6a32d

+ 75 - 15
EVSE/Modularization/ocppfiles/MessageHandler.c

@@ -112,6 +112,7 @@ void processUnkownKey(void);
 
 struct InterLock
 {
+	unsigned char isSentUnplug[CONNECTOR_QUANTITY];
 	unsigned char isGetDiagnosticGoing:1;
 	unsigned char isUpdateFirmwareGoing:1;
 }interLock;
@@ -5047,14 +5048,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != ChademoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn != ChademoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							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;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						ChademoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus;
@@ -5105,14 +5111,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn != CcsPreviousConnectorPlugIn[index]) )//if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]/*PRE_SYS_MODE[gun_index]*/ )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							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;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus;
@@ -5163,14 +5174,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != GbPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn != GbPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							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;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus;
@@ -5213,14 +5229,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != DoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn != DoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							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;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						DoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus;
@@ -5270,14 +5291,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A))
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							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;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
@@ -5731,6 +5757,35 @@ int sendDataTransferRequest(int gun_index)
 	return result;
 }
 
+int sendUnplugByDataTransferRequest(int gun_index)
+{
+	mtrace();
+	char message[1000]={0};
+	char guid[37]={0};
+	char tempdata[65]={0};
+	int result = FAIL;
+
+	random_uuid(guid);
+	sprintf(message,"%d,[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
+			(gun_index+1),
+			MESSAGE_TYPE_CALL,
+			guid,
+			ShmOCPP16Data->DataTransfer[gun_index].VendorId,
+			ShmOCPP16Data->DataTransfer[gun_index].MessageId,
+			ShmOCPP16Data->DataTransfer[gun_index].Data);
+
+	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
+	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
+	{
+		result = PASS;
+		DEBUG_INFO("DataTransfer mapItem pass\n");
+	}
+
+	queue_operation(QUEUE_OPERATION_ADD, guid, message);
+
+	return result;
+}
+
 int sendDiagnosticsStatusNotificationRequest(char *status)
 {
 	mtrace();
@@ -20453,6 +20508,11 @@ void GetStartTransactionIdTag(int gun_index)
 	strcpy((char *)StartTransactionIdTagTemp, (const char *)ShmOCPP16Data->StartTransaction[gun_index].IdTag);
 }
 
+int GetStartTransactionId(int gun_index)
+{
+	return ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId;
+}
+
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction)
 {
 	char ch;

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

@@ -465,6 +465,7 @@ void GetStartTransactionIdTag(int gun_index);
 int sendAuthorizeRequest(int gun_index);
 int sendBootNotificationRequest(void);
 int sendDataTransferRequest(int gun_index);
+int sendUnplugByDataTransferRequest(int gun_index);
 int sendFirmwareVersionByDataTransfer(void);
 int sendDiagnosticsStatusNotificationRequest(char *status);
 int sendFirmwareStatusNotificationRequest(char *status);
@@ -587,6 +588,7 @@ int GetOcppServerURL();
 int GetOcppPath();
 int GetOcppPort();
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction);
+int GetStartTransactionId(int gun_index);
 void SetTransactionIdZero(int transactionId);
 void GetChargingProfileRequest(int gunindex);
 void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[]);

+ 164 - 243
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -918,272 +918,193 @@ int showqueue()
 	return TRUE;
 }
 
-int sentqueue(){
+int sentqueue()
+{
+	int result = FAIL;
+	struct stat stats;
 	FILE *fp;
-	int result = FALSE; // 1: TRUE  0:FALSE
-	int temptransactionId = 0, gettransactionId = 0;
-	int tempconnectorId = 0;
-	//int gunIndex = 0;
-	char guid[37]={0};
-	char tempdata[65]={0};
-	char key_value[65]={0};
-	int IsStopTransaction = FALSE;
-	//int IsconnectorIdNULL = FALSE;
-	//int IsIdtagNULL = FALSE;
+	json_object *obj = NULL;
+	json_object *objPayload = NULL;
+	json_object *objData = NULL;
+
+	char cmd[128];
 	char str[QUEUE_MESSAGE_LENGTH]={0};
-	char strcomposite[QUEUE_MESSAGE_LENGTH]={0};
-	char rmFileCmd[100]={0};
-	char connectorStr[2]={0};
-	struct stat stats;
-	char sstr[28]={0};
-	unsigned char IdtagStr[20]={0};
-	unsigned char timestampStr[30]={0};
-	int tempmeterStart = 0;
-	int tempreservationId = 0;
-	int c = 0;
-	char *loc;
+	char queueData[QUEUE_MESSAGE_LENGTH]={0};
+	char payload[QUEUE_MESSAGE_LENGTH]={0};
+	char key_value[65]={0};
+	char hashData[65]={0};
+	char action[32];
+	char guid[37];
+	uint8_t	connectorId;
 
 	DEBUG_INFO("Sent queue.\n");
 
 	stat("/Storage/OCPP", &stats);
 
 	// Check for directory existence
-	if (S_ISDIR(stats.st_mode) == 1)
-	{
-		//DEBUG_INFO("\n OCPP directory exist \n");
-	}
-	else
+	if (S_ISDIR(stats.st_mode) != 1)
 	{
 		//DEBUG_INFO("\n OCPP directory not exist, create dir \n");
-		sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
-		system(rmFileCmd);
+		sprintf(cmd, "mkdir -p /Storage/OCPP");
+		system(cmd);
 	}
 
-	memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
-
-	/* opening file for reading */
-	fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
-	if(fp == NULL) {
-		DEBUG_INFO("Error opening file");
-		return FALSE;
+	if((fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r")) == NULL)
+	{
+		DEBUG_ERROR("Error opening file");
 	}
-
-	if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL ) {
-
-		//---- writing content to stdout ---//
-
-		//*********************Start: StopTransaction***************************/
-		loc = strstr(str, "StopTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			IsStopTransaction = TRUE;
-		}
-
-		memset(connectorStr,0,ARRAY_SIZE(connectorStr));
-		strncpy(connectorStr, str, 1);
-		tempconnectorId = atoi(connectorStr);
-		//*********************End: StopTransaction***************************/
-
-	#if 0
-		//*********************Start:connectorId***************************/
-		loc = strstr(str, "connectorId");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[strlen("connectorId")+2+c] != ',')
-			{
-				sstr[c] = loc[strlen("connectorId")+2+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			tempconnectorId = atoi(sstr);
-		}
-	//	else
-	//	{
-	//		IsconnectorIdNULL = TRUE;
-	//	}
-		//*********************End:connectorId***************************/
-	#endif
-
-		//*********************Start:idTag***************************/
-		loc = strstr(str, "idTag");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-		}
-	//	else
-	//	{
-	//		IsIdtagNULL = TRUE;
-	//	}
-		//*********************End:idTag***************************/
-
-
-		//*********************Start: StartTransaction***************************/
-		loc = strstr(str, "StartTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
+	else
+	{
+		// parse message content
+		if(fgets(str, QUEUE_MESSAGE_LENGTH, fp) != NULL)
 		{
-			// [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
-			//DEBUG_INFO("\n sent queue StartTransaction\n");
-			if(tempconnectorId > 0)
-			{
-				sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
-			}
+			// parse connectorId
+			connectorId = (str[0]-0x30);
+			memcpy(&queueData, &str[2], strlen(str)-2);
 
-			//GUID
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (str[6+c] != '\"')
+			obj = json_tokener_parse(queueData);
+			if(!is_error(obj))
 			{
-				sstr[c] = str[6+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy(guid, sstr);
-
-
-			//Idtag
-			loc = strstr(str, "idTag");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-
-			//meterStart
-			loc = strstr(str, "meterStart");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("meterStart")+2+c] != ',')
+				sprintf(guid, "%s", json_object_get_string(json_object_array_get_idx(obj, 1)));
+				sprintf(action, "%s", json_object_get_string(json_object_array_get_idx(obj, 2)));
+				sprintf(payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 3), JSON_C_TO_STRING_PLAIN));
+				objPayload = json_tokener_parse(payload);
+				if(!is_error(objPayload))
 				{
-					sstr[c] = loc[strlen("meterStart")+2+c];
-					c++;
-				}
-				sstr[c] = '\0';
-				tempmeterStart = atoi(sstr);
-
-			}
+					if(strstr(action, "StartTransaction") != NULL)
+					{
+						if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
+						{
+							//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
+						}
+						else
+						{
+							char idtag[21]={0};
+							char timestamp[36]={0};
+							int meterStart=0;
+							int reservationId=-1;
+							sprintf(hashData, "StartTransaction,%d", (connectorId-1));
+							hashmap_operation(HASH_OP_ADD, guid, hashData);
+
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							if(json_object_object_get(objPayload, "meterStart") != NULL)
+							{
+								meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
+							}
+
+							if(json_object_object_get(objPayload, "reservationId") != NULL)
+							{
+								reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
+							}
+
+							if(json_object_object_get(objPayload, "timestamp") != NULL)
+							{
+								sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
+							}
+
+							FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
+							//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
+						}
+
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+						json_object_put(objPayload);
+					}
+					else if((strstr(action, "MeterValues") != NULL) || strstr(action, "StopTransaction") != NULL)
+					{
+						char idtag[21]={0};
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(json_object_object_get(objPayload, "transactionId") != NULL)
+						{
+							transactionId_org = json_object_get_int(json_object_object_get(objPayload, "transactionId"));
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+							GetStartTransactionIdTag(connectorId-1);
+							transactionId_map = GetTransactionId(connectorId, (unsigned char*)idtag, ((strstr(action, "StopTransaction") != NULL)?YES:NO));
+
+							DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+							DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+							DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+							DEBUG_INFO("original  IdtagStr        = %s\n", "");
+							if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+							{
+								//replace transactionId
+								json_object_object_add(objPayload, "transactionId", json_object_new_int(transactionId_map));
+							}
+							else
+							{
+								transactionId_map = transactionId_org;
+							}
+							DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+						}
+
+						json_object_array_put_idx(obj, 3, objPayload);
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+
+						if(strstr(action, "StopTransaction") != NULL)
+							queueOpInfo.stopTransactionId = transactionId_map;
+					}
+					else
+					{
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(strstr(json_object_get_string(json_object_object_get(objPayload, "messageId")), "ConnectorUnplugged") != NULL)
+						{
+							objData = json_tokener_parse(json_object_get_string(json_object_object_get(objPayload, "data")));
+							if(!is_error(objData))
+							{
+								transactionId_org = json_object_get_int(json_object_object_get(objData, "idTx"));
+
+								//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+								GetStartTransactionIdTag(connectorId-1);
+								transactionId_map = GetTransactionId(connectorId, (unsigned char*)"", NO);
+
+								DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+								DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+								DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+								DEBUG_INFO("original  IdtagStr        = %s\n", "");
+								if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else if((transactionId_map == 0) && (transactionId_org == 0))
+								{
+									//replace transactionId
+									transactionId_map = GetStartTransactionId(connectorId-1);
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else
+								{
+									transactionId_map = transactionId_org;
+								}
+								DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+
+								json_object_object_add(objPayload, "data", json_object_new_string(json_object_to_json_string_ext(objData, JSON_C_TO_STRING_PLAIN)));
+								json_object_array_put_idx(obj, 3, objPayload);
+								LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+							}
+						}
+					}
 
-			//reservationId
-			loc = strstr(str, "reservationId");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("reservationId")+2+c] != ',')
-				{
-					sstr[c] = loc[strlen("reservationId")+2+c];
-					c++;
+					result = PASS;
 				}
-				sstr[c] = '\0';
-				tempreservationId = atoi(sstr);
-
-			}
-
-			//timestamp
-			loc = strstr(str, "timestamp");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("timestamp")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("timestamp")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)timestampStr, sstr);
-
-
-			if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
-			{
-				//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
-			}
-			else
-			{
-				hashmap_operation(HASH_OP_ADD, guid, tempdata);
-				FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
-				//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
 			}
+			json_object_put(obj);
 		}
-		//*********************End: StartTransaction***************************/
-
-
-		//****************transactionId********************/
-		 c=0;
-		 loc = strstr(str, "transactionId");
-		 memset(sstr ,0, ARRAY_SIZE(sstr) );
-		 if(loc != NULL)
-		 {
-			 // Only MeterValue with transactionId & StopTransaction will arrive here
-			 while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
-			 {
-				sstr[c] = loc[strlen("transactionId")+2+c];
-				c++;
-			 }
-
-			sstr[c] = '\0';
-			temptransactionId = atoi(sstr);
-
-
-			//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
-			GetStartTransactionIdTag(tempconnectorId-1);
-			gettransactionId = GetTransactionId(tempconnectorId, IdtagStr, IsStopTransaction);
-
-			DEBUG_INFO("queue map transactionId   = %d\n", gettransactionId);
-			DEBUG_INFO("original  connectorId     = %d\n", tempconnectorId);
-			DEBUG_INFO("original  transactionId   = %d\n", temptransactionId);
-			DEBUG_INFO("original  IdtagStr        = %s\n", IdtagStr);
-			if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
-			{
-				//replace transactionId of metervalue or stopTransaction
-				strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
-				sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
-				strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
-				LWS_Send(strcomposite+2); // skip 2 bytes String -> Connector ID,
-			}
-			else
-			{
-				LWS_Send(str+2);  // skip 2 bytes String -> Connector ID
-				gettransactionId = temptransactionId;
-			}
-
-			DEBUG_INFO("Final transactionId       = %d\n", gettransactionId);
-			if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
-			{
-				queueOpInfo.stopTransactionId = gettransactionId;
-				//SetTransactionIdZero(gettransactionId);
-			}
-		 }
-		 else
-		 {
-			 // MeterValue without transactionId & StartTransaction arrive here
-			 LWS_Send(str+2);
-		 }
-
-		result = TRUE;
-	}
-	else
-	{
-		result = FALSE;
 	}
 	fclose(fp);
+
 	return result;
 }
 

+ 75 - 15
EVSE/Modularization/ocppph/MessageHandler.c

@@ -113,6 +113,7 @@ void processUnkownKey(void);
 
 struct InterLock
 {
+	unsigned char isSentUnplug[CONNECTOR_QUANTITY];
 	unsigned char isGetDiagnosticGoing:1;
 	unsigned char isUpdateFirmwareGoing:1;
 }interLock;
@@ -4567,14 +4568,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != ChademoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn != ChademoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						ChademoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus;
@@ -4625,14 +4631,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn != CcsPreviousConnectorPlugIn[index]) )//if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]/*PRE_SYS_MODE[gun_index]*/ )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus;
@@ -4683,14 +4694,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != GbPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn != GbPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus;
@@ -4733,14 +4749,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != DoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn != DoPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0))
+						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 0) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						DoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus;
@@ -4790,14 +4811,19 @@ void CheckSystemValue(void)
 					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A))
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A) && !interLock.isSentUnplug[gun_index])
 						{
-							uint8_t ts[20];
+							uint8_t ts[36];
 							getNowDatetime(ts);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].VendorId, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].MessageId, "ConnectorUnplugged");
 							sprintf((char*)ShmOCPP16DataPH->DataTransfer[gun_index].Data, "{\\\"idTx\\\":%d,\\\"timestamp\\\":\\\"%s\\\"}", ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId, ts);
-							ShmOCPP16DataPH->CsMsg.bits[gun_index].DataTransferReq = 1;
+							sendUnplugByDataTransferRequest(gun_index);
+							interLock.isSentUnplug[gun_index] = 1;
+						}
+						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE))
+						{
+							interLock.isSentUnplug[gun_index] = 0;
 						}
 
 						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
@@ -5262,6 +5288,35 @@ int sendDataTransferRequest(int gun_index)
 	return result;
 }
 
+int sendUnplugByDataTransferRequest(int gun_index)
+{
+	mtrace();
+	char message[1000]={0};
+	char guid[37]={0};
+	char tempdata[65]={0};
+	int result = FAIL;
+
+	random_uuid(guid);
+	sprintf(message,"%d,[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
+			(gun_index+1),
+			MESSAGE_TYPE_CALL,
+			guid,
+			ShmOCPP16DataPH->DataTransfer[gun_index].VendorId,
+			ShmOCPP16DataPH->DataTransfer[gun_index].MessageId,
+			ShmOCPP16DataPH->DataTransfer[gun_index].Data);
+
+	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
+	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
+	{
+		result = PASS;
+		DEBUG_INFO("DataTransfer mapItem pass\n");
+	}
+
+	queue_operation(QUEUE_OPERATION_ADD, guid, message);
+
+	return result;
+}
+
 int sendDiagnosticsStatusNotificationRequest(char *status)
 {
 	mtrace();
@@ -19682,6 +19737,11 @@ void GetStartTransactionIdTag(int gun_index)
 	strcpy((char *)StartTransactionIdTagTemp, (const char *)ShmOCPP16DataPH->StartTransaction[gun_index].IdTag);
 }
 
+int GetStartTransactionId(int gun_index)
+{
+	return ShmOCPP16DataPH->StartTransaction[gun_index].ResponseTransactionId;
+}
+
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction)
 {
 	char ch;

+ 2 - 0
EVSE/Modularization/ocppph/MessageHandler.h

@@ -461,6 +461,7 @@ void GetStartTransactionIdTag(int gun_index);
 int sendAuthorizeRequest(int gun_index);
 int sendBootNotificationRequest(void);
 int sendDataTransferRequest(int gun_index);
+int sendUnplugByDataTransferRequest(int gun_index);
 int sendFirmwareVersionByDataTransfer(void);
 int sendDiagnosticsStatusNotificationRequest(char *status);
 int sendFirmwareStatusNotificationRequest(char *status);
@@ -583,6 +584,7 @@ int GetOcppServerURL();
 int GetOcppPath();
 int GetOcppPort();
 int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction);
+int GetStartTransactionId(int gun_index);
 void SetTransactionIdZero(int transactionId);
 void GetChargingProfileRequest(int gunindex);
 void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[]);

+ 171 - 244
EVSE/Modularization/ocppph/Module_OcppBackend.c

@@ -916,272 +916,199 @@ int showqueue()
 	return TRUE;
 }
 
-int sentqueue(){
+int sentqueue()
+{
+	int result = FAIL;
+	struct stat stats;
 	FILE *fp;
-	int result = FALSE; // 1: TRUE  0:FALSE
-	int temptransactionId = 0, gettransactionId = 0;
-	int tempconnectorId = 0;
-	//int gunIndex = 0;
-	char guid[37]={0};
-	char tempdata[65]={0};
-	char key_value[65]={0};
-	int IsStopTransaction = FALSE;
-	//int IsconnectorIdNULL = FALSE;
-	//int IsIdtagNULL = FALSE;
+	json_object *obj = NULL;
+	json_object *objPayload = NULL;
+	json_object *objData = NULL;
+
+	char cmd[128];
 	char str[QUEUE_MESSAGE_LENGTH]={0};
-	char strcomposite[QUEUE_MESSAGE_LENGTH]={0};
-	char rmFileCmd[100]={0};
-	char connectorStr[2]={0};
-	struct stat stats;
-	char sstr[28]={0};
-	unsigned char IdtagStr[20]={0};
-	unsigned char timestampStr[30]={0};
-	int tempmeterStart = 0;
-	int tempreservationId = 0;
-	int c = 0;
-	char *loc;
+	char queueData[QUEUE_MESSAGE_LENGTH]={0};
+	char payload[QUEUE_MESSAGE_LENGTH]={0};
+	char key_value[65]={0};
+	char hashData[65]={0};
+	char action[32];
+	char guid[37];
+	uint8_t	connectorId;
 
 	DEBUG_INFO("Sent queue.\n");
 
-	stat("/Storage/OCPP_PH", &stats);
+	stat("/Storage/OCPP", &stats);
 
 	// Check for directory existence
-	if (S_ISDIR(stats.st_mode) == 1)
-	{
-		//DEBUG_INFO("\n OCPP directory exist \n");
-	}
-	else
+	if (S_ISDIR(stats.st_mode) != 1)
 	{
 		//DEBUG_INFO("\n OCPP directory not exist, create dir \n");
-		sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP_PH");
-		system(rmFileCmd);
+		sprintf(cmd, "mkdir -p /Storage/OCPP");
+		system(cmd);
 	}
 
-	memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
-
-	/* opening file for reading */
-	fp = fopen("/Storage/OCPP_PH/TransactionRelatedQueue" , "r");
-	if(fp == NULL) {
-		DEBUG_INFO("Error opening file");
-		return FALSE;
+	if((fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r")) == NULL)
+	{
+		DEBUG_ERROR("Error opening file");
 	}
-
-	if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL ) {
-
-		//---- writing content to stdout ---//
-
-		//*********************Start: StopTransaction***************************/
-		loc = strstr(str, "StopTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			IsStopTransaction = TRUE;
-		}
-
-		memset(connectorStr,0,ARRAY_SIZE(connectorStr));
-		strncpy(connectorStr, str, 1);
-		tempconnectorId = atoi(connectorStr);
-		//*********************End: StopTransaction***************************/
-
-	#if 0
-		//*********************Start:connectorId***************************/
-		loc = strstr(str, "connectorId");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[strlen("connectorId")+2+c] != ',')
-			{
-				sstr[c] = loc[strlen("connectorId")+2+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			tempconnectorId = atoi(sstr);
-		}
-	//	else
-	//	{
-	//		IsconnectorIdNULL = TRUE;
-	//	}
-		//*********************End:connectorId***************************/
-	#endif
-
-		//*********************Start:idTag***************************/
-		loc = strstr(str, "idTag");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
-		{
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-		}
-	//	else
-	//	{
-	//		IsIdtagNULL = TRUE;
-	//	}
-		//*********************End:idTag***************************/
-
-
-		//*********************Start: StartTransaction***************************/
-		loc = strstr(str, "StartTransaction");
-		c = 0;
-		memset(sstr ,0, ARRAY_SIZE(sstr) );
-		if(loc != NULL)
+	else
+	{
+		// parse message content
+		if(fgets(str, QUEUE_MESSAGE_LENGTH, fp) != NULL)
 		{
-			// [2,0200000000000000000000000001584415776,StartTransaction,{connectorId:1,idTag:123,meterStart:100,reservationId:0,timestamp:2020-03-17T03:29:36Z}]
-			//DEBUG_INFO("\n sent queue StartTransaction\n");
-			if(tempconnectorId > 0)
-			{
-				sprintf(tempdata, "StartTransaction,%d", (tempconnectorId-1));
-			}
+			// parse connectorId
+			connectorId = (str[0]-0x30);
+			memcpy(&queueData, &str[2], strlen(str)-2);
 
-			//GUID
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (str[6+c] != '\"')
+			obj = json_tokener_parse(queueData);
+			if(!is_error(obj))
 			{
-				sstr[c] = str[6+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy(guid, sstr);
-
-
-			//Idtag
-			loc = strstr(str, "idTag");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("idTag")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("idTag")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)IdtagStr, sstr);
-
-			//meterStart
-			loc = strstr(str, "meterStart");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("meterStart")+2+c] != ',')
+				sprintf(guid, "%s", json_object_get_string(json_object_array_get_idx(obj, 1)));
+				sprintf(action, "%s", json_object_get_string(json_object_array_get_idx(obj, 2)));
+				sprintf(payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 3), JSON_C_TO_STRING_PLAIN));
+				objPayload = json_tokener_parse(payload);
+				if(!is_error(objPayload))
 				{
-					sstr[c] = loc[strlen("meterStart")+2+c];
-					c++;
-				}
-				sstr[c] = '\0';
-				tempmeterStart = atoi(sstr);
-
-			}
+					if(strstr(action, "StartTransaction") != NULL)
+					{
+						if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
+						{
+							//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
+						}
+						else
+						{
+							char idtag[21]={0};
+							char timestamp[36]={0};
+							int meterStart=0;
+							int reservationId=-1;
+							sprintf(hashData, "StartTransaction,%d", (connectorId-1));
+							hashmap_operation(HASH_OP_ADD, guid, hashData);
+
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							if(json_object_object_get(objPayload, "meterStart") != NULL)
+							{
+								meterStart = json_object_get_int(json_object_object_get(objPayload, "meterStart"));
+							}
+
+							if(json_object_object_get(objPayload, "reservationId") != NULL)
+							{
+								reservationId = json_object_get_int(json_object_object_get(objPayload, "reservationId"));
+							}
+
+							if(json_object_object_get(objPayload, "timestamp") != NULL)
+							{
+								sprintf(timestamp, "%s", json_object_get_string(json_object_object_get(objPayload, "timestamp")));
+							}
+
+							FillStartTransaction(connectorId, (unsigned char*)idtag, meterStart, reservationId, (unsigned char*)timestamp);
+							//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
+						}
+
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+						json_object_put(objPayload);
+					}
+					else if((strstr(action, "MeterValues") != NULL) || strstr(action, "StopTransaction") != NULL)
+					{
+						char idtag[21]={0};
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(json_object_object_get(objPayload, "transactionId") != NULL)
+						{
+							transactionId_org = json_object_get_int(json_object_object_get(objPayload, "transactionId"));
+							if(json_object_object_get(objPayload, "idTag") != NULL)
+							{
+								sprintf(idtag, "%s", json_object_get_string(json_object_object_get(objPayload, "idTag")));
+							}
+
+							//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+							GetStartTransactionIdTag(connectorId-1);
+							transactionId_map = GetTransactionId(connectorId, (unsigned char*)idtag, ((strstr(action, "StopTransaction") != NULL)?YES:NO));
+
+							DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+							DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+							DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+							DEBUG_INFO("original  IdtagStr        = %s\n", "");
+							if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+							{
+								//replace transactionId
+								json_object_object_add(objPayload, "transactionId", json_object_new_int(transactionId_map));
+							}
+							else if((transactionId_map == 0) && (transactionId_org == 0))
+							{
+								//replace transactionId
+								transactionId_map = GetStartTransactionId(connectorId-1);
+								json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+							}
+							else
+							{
+								transactionId_map = transactionId_org;
+							}
+							DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+						}
+
+						json_object_array_put_idx(obj, 3, objPayload);
+						LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+
+						if(strstr(action, "StopTransaction") != NULL)
+							queueOpInfo.stopTransactionId = transactionId_map;
+					}
+					else
+					{
+						int transactionId_org=0;
+						int transactionId_map=0;
+
+						if(strstr(json_object_get_string(json_object_object_get(objPayload, "messageId")), "ConnectorUnplugged") != NULL)
+						{
+							objData = json_tokener_parse(json_object_get_string(json_object_object_get(objPayload, "data")));
+							if(!is_error(objData))
+							{
+								transactionId_org = json_object_get_int(json_object_object_get(objData, "idTx"));
+
+
+								//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
+								GetStartTransactionIdTag(connectorId-1);
+								transactionId_map = GetTransactionId(connectorId, (unsigned char*)"", NO);
+
+								DEBUG_INFO("queue map transactionId   = %d\n", transactionId_map);
+								DEBUG_INFO("original  connectorId     = %d\n", connectorId);
+								DEBUG_INFO("original  transactionId   = %d\n", transactionId_org);
+								DEBUG_INFO("original  IdtagStr        = %s\n", "");
+								if((transactionId_map != 0)&&(transactionId_org != transactionId_map))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(transactionId_map));
+								}
+								else if((transactionId_map == 0) && (transactionId_org == 0))
+								{
+									//replace transactionId
+									json_object_object_add(objData, "idTx", json_object_new_int(GetStartTransactionId(connectorId-1)));
+								}
+								else
+								{
+									transactionId_map = transactionId_org;
+								}
+								DEBUG_INFO("Final transactionId       = %d\n", transactionId_map);
+
+								json_object_object_add(objPayload, "data", json_object_new_string(json_object_to_json_string_ext(objData, JSON_C_TO_STRING_PLAIN)));
+								json_object_array_put_idx(obj, 3, objPayload);
+								LWS_Send((char*)json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
+							}
+						}
+					}
 
-			//reservationId
-			loc = strstr(str, "reservationId");
-			c = 0;
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			if(loc != NULL)
-			{
-				while (loc[strlen("reservationId")+2+c] != ',')
-				{
-					sstr[c] = loc[strlen("reservationId")+2+c];
-					c++;
+					result = PASS;
 				}
-				sstr[c] = '\0';
-				tempreservationId = atoi(sstr);
-
-			}
-
-			//timestamp
-			loc = strstr(str, "timestamp");
-			memset(sstr ,0, ARRAY_SIZE(sstr) );
-			c=0;
-			while (loc[3+strlen("timestamp")+c] != '\"')
-			{
-				sstr[c] = loc[3+strlen("timestamp")+c];
-				c++;
-			}
-			sstr[c] = '\0';
-			strcpy((char*)timestampStr, sstr);
-
-
-			if(hashmap_operation(HASH_OP_GET, guid, key_value) == TRUE)
-			{
-				//DEBUG_INFO("\n 1. sent queue guid=%s\n",guid);
-			}
-			else
-			{
-				hashmap_operation(HASH_OP_ADD, guid, tempdata);
-				FillStartTransaction(tempconnectorId, IdtagStr, tempmeterStart, tempreservationId, timestampStr);
-				//DEBUG_INFO("\n 2. sent queue guid=%s\n",guid);
 			}
+			json_object_put(obj);
 		}
-		//*********************End: StartTransaction***************************/
-
-
-		//****************transactionId********************/
-		 c=0;
-		 loc = strstr(str, "transactionId");
-		 memset(sstr ,0, ARRAY_SIZE(sstr) );
-		 if(loc != NULL)
-		 {
-			 // Only MeterValue with transactionId & StopTransaction will arrive here
-			 while ((loc[strlen("transactionId")+2+c] != '}') && (loc[strlen("transactionId")+2+c] != ','))
-			 {
-				sstr[c] = loc[strlen("transactionId")+2+c];
-				c++;
-			 }
-
-			sstr[c] = '\0';
-			temptransactionId = atoi(sstr);
-
-
-			//Get IdTag from StartTransaction , store to StartTransactionIdTagTemp, For StopTransaction usage in Queue (StartTransaction. StopTransaction user id different), get actual TransactionId
-			GetStartTransactionIdTag(tempconnectorId-1);
-			gettransactionId = GetTransactionId(tempconnectorId, IdtagStr, IsStopTransaction);
-
-			DEBUG_INFO("queue map transactionId   = %d\n", gettransactionId);
-			DEBUG_INFO("original  connectorId     = %d\n", tempconnectorId);
-			DEBUG_INFO("original  transactionId   = %d\n", temptransactionId);
-			DEBUG_INFO("original  IdtagStr        = %s\n", IdtagStr);
-			if((gettransactionId != 0)&&(temptransactionId != gettransactionId))
-			{
-				//replace transactionId of metervalue or stopTransaction
-				strncpy(strcomposite,str, (loc-str)+2+strlen("transactionId"));
-				sprintf(strcomposite+((loc-str)+2+strlen("transactionId")),"%d",gettransactionId);
-				strcat(strcomposite, loc+strlen("transactionId")+2+c); // 把 字串中transactionId後面的字串串接到 strcomposite後面
-				LWS_Send(strcomposite+2); // skip 2 bytes String -> Connector ID,
-			}
-			else
-			{
-				LWS_Send(str+2);  // skip 2 bytes String -> Connector ID
-				gettransactionId = temptransactionId;
-			}
-
-			DEBUG_INFO("Final transactionId       = %d\n", gettransactionId);
-			if(IsStopTransaction == TRUE)//if((IsStopTransaction == TRUE)&&(gettransactionId != 0))
-			{
-				queueOpInfo.stopTransactionId = gettransactionId;
-				//SetTransactionIdZero(gettransactionId);
-			}
-		 }
-		 else
-		 {
-			 // MeterValue without transactionId & StartTransaction arrive here
-			 LWS_Send(str+2);
-		 }
-
-		result = TRUE;
-	}
-	else
-	{
-		result = FALSE;
 	}
 	fclose(fp);
+
 	return result;
 }
 

+ 4 - 4
EVSE/Projects/AX80/Apps/main.c

@@ -4705,6 +4705,7 @@ void checkStopReason(uint8_t gun_index)
 		else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP)
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EmergencyStop");
+			memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		}
 		else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES))
 		{
@@ -4744,6 +4745,7 @@ void checkStopReason(uint8_t gun_index)
 		else
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other");
+			memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag));
 		}
 		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
@@ -5450,8 +5452,7 @@ int main(void)
 					// Alarm event check
 					if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode>0) ||
 						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail ||
-						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP ||
-						ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP)
 					{
 						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_ALARM)
 						{
@@ -6480,8 +6481,7 @@ int main(void)
 
 						if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == 0) &&
 						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail &&
-						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP &&
-						   !ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail)
+						   !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP)
 						{
 							if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) &&
 								!ShmCharger->gun_info[gun_index].isEmergencyStopReport)