瀏覽代碼

[Add][AW-CCS][main]

2021.07.06 / Folus Wen

Actions:
1. Check task change scan period to 10 seconds.
2. Implement send charging receipt mail by Phihong back-end API for CDFA certificate.

Files:
1. As follow commit history

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

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 3 年之前
父節點
當前提交
75beb13bd2
共有 2 個文件被更改,包括 158 次插入20 次删除
  1. 157 19
      EVSE/Projects/AW-CCS/Apps/main.c
  2. 1 1
      EVSE/Projects/AW-CCS/Apps/main.h

+ 157 - 19
EVSE/Projects/AW-CCS/Apps/main.c

@@ -1,10 +1,12 @@
 #include	"define.h"
 #include 	"main.h"
 
+//#define CDFA_CERTIFICATE	// Only enable for CDFA certificate to send receipt by Phihong back end API
 
 //==========================
 // System basic sample constant
 //==========================
+#define is_error(ptr) 					((unsigned long)ptr > (unsigned long)-4000L)
 #define ARRAY_SIZE(A)					(sizeof(A) / sizeof(A[0]))
 #define PASS							1
 #define FAIL							-1
@@ -1192,9 +1194,91 @@ int CreatShareMemory()
     return result;
 }
 
-//===============================================
+//======================================================
+// Call WEBAPI to mail receipt (Only for CDFA verify)
+//======================================================
+#ifdef CDFA_CERTIFICATE
+int sendReceiptMail(char *startDateTime, char *stopDateTime, char *receiptInfo)
+{
+	int result = FAIL;
+	char reciever[128];
+	char subject[128];
+	char content[8192];
+	char priceDetail[4098]={0};
+	char cmdBuf[8192];
+
+	double totalEnergy;
+	double totalPrice;
+	json_object *detailPrice = json_tokener_parse(receiptInfo);
+
+	if(!is_error(detailPrice))
+	{
+		if(json_object_object_get(detailPrice, "totalChargedEnergy") != NULL)
+			totalEnergy = json_object_get_double(json_object_object_get(detailPrice, "totalChargedEnergy"));
+
+		if(json_object_object_get(detailPrice, "totalPrice") != NULL)
+			totalPrice = json_object_get_double(json_object_object_get(detailPrice, "totalPrice"));
+
+		if(json_object_object_get(detailPrice, "receiptDetail") != NULL)
+		{
+			for(int idx=0;idx<json_object_array_length(json_object_object_get(detailPrice, "receiptDetail"));idx++)
+			{
+				sprintf(priceDetail, "%s---%02d:00, %.4f KWH @ $ %.2f = $ %.2f<br/>\n", priceDetail
+																                 , json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "hour"))
+																			     , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "chargedEnergy"))
+																				 , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "unitPrice"))
+																				 , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "periodPrice")));
+			}
+		}
+
+	}
+	json_object_put(detailPrice);
+
+	// Generate mail content
+	sprintf(reciever, "folus_wen@phihong.com.tw");
+	sprintf(subject, "Charging Receipt From %s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+	sprintf(content, "<img src=\"https://www.phihong.com/images/logo.png\"/><br/>\n"
+					 "<h1>Receipt of charging on %s</h1><br/>\n"
+					 "<b>Location Name:</b> CDFA Lab<br/>\n"
+					 "<b>Location Address:</b> xxxxxxxxxxx<br/>\n"
+					 "<b>EVSE ID:</b> %s<br/>\n"
+					 "<b>Maximum Rate of Energy Transfer:</b> 11.5 KW AC<br/>\n"
+					 "<b>Charging start date time:</b> %s<br/>\n"
+					 "<b>Charging stop date time:</b> %s<br/>\n"
+					 "<b>Energy Delivered:</b> %.4f KWH<br/>\n"
+					 "<b>Cost of Charging:</b><br/>\n"
+				     "%s"
+					 "***Total charged cost: $ %.2f<br/>\n"
+					 "<br/>\n"
+					 "<br/>\n"
+					 "%s<br/>\n"
+					 "47800 Fremont Blvd.<br/>\n"
+					 "Fremont, CA 94538, USA<br/>\n", startDateTime
+					 	 	 	 	 	 	   	    , ShmSysConfigAndInfo->SysConfig.ChargeBoxId
+													, startDateTime
+												    , stopDateTime
+												    , totalEnergy
+												    , priceDetail
+												    , totalPrice
+												    , ShmSysConfigAndInfo->SysConfig.chargePointVendor);
+
+	json_object *post = json_object_new_object();
+	json_object_object_add(post, "Receiver", json_object_new_string(reciever));
+	json_object_object_add(post, "Subject", json_object_new_string(subject));
+	json_object_object_add(post, "Body", json_object_new_string(content));
+	json_object_object_add(post, "UseHtml", json_object_new_boolean(1));
+	// Call WEBAPI
+	sprintf(cmdBuf, "curl -X POST -k -d '%s' -H \"Content-Type: application/json\" https://ocpp.phihong.com.tw:5014/api/Notification/ &", json_object_to_json_string_ext(post, JSON_C_TO_STRING_PLAIN));
+	system(cmdBuf);
+	//DEBUG_INFO("cmdBuf: %s\n", cmdBuf);
+	json_object_put(post);
+
+	return result;
+}
+#endif	/* CDFA_CERTIFICATE */
+//======================================================
 // SQLite3 related routine
-//===============================================
+//======================================================
 int getReceiptInfo(uint8_t gun_index, char *receiptInfo)
 {
 	int result = PASS;
@@ -1229,6 +1313,8 @@ int getReceiptInfo(uint8_t gun_index, char *receiptInfo)
 	sprintf(receiptInfo, "%s", json_object_to_json_string_ext(receipt, JSON_C_TO_STRING_PLAIN));
 	json_object_put(receipt);
 
+	//DEBUG_INFO("receiptInfo: %s\n", receiptInfo);
+
 	return result;
 }
 
@@ -1369,6 +1455,13 @@ int DB_Check_Record_Buf(sqlite3 *db, int gun_index)
 				{
 					DEBUG_INFO( "Copy local charging record buffer successfully\n");
 				}
+
+#ifdef CDFA_CERTIFICATE
+				// Only for CDFA certificate
+				sendReceiptMail(rs[(idxRow*cols)+4],
+								rs[(idxRow*cols)+5],
+								rs[(idxRow*cols)+10]);
+#endif /* CDFA_CERTIFICATE */
 			}
 
 			// Delete buffer
@@ -1399,6 +1492,9 @@ int DB_Update_Record_Buf(sqlite3 *db, int gun_index)
 	int result = PASS;
 	char* errMsg = NULL;
 	char sqlStr[4096];
+	char receiptInfo[2048];
+
+	getReceiptInfo(gun_index, receiptInfo);
 
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
@@ -1414,12 +1510,21 @@ int DB_Update_Record_Buf(sqlite3 *db, int gun_index)
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
 					    "Power Loss",
-					    ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+#ifdef CDFA_CERTIFICATE
+						receiptInfo);// Only for CDFA certificate
+#else
+						ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+#endif /* CDFA_CERTIFICATE */
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 		sprintf(sqlStr, "insert into charging_record_buffer(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) "
- 					    "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');",
+#ifdef CDFA_CERTIFICATE
+				"values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');",
+#else
+				"values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');",
+#endif /* CDFA_CERTIFICATE */
+
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
 					    ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
@@ -1430,7 +1535,12 @@ int DB_Update_Record_Buf(sqlite3 *db, int gun_index)
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
 					    "Power Loss",
-					    ShmOCPP20Data->CostUpdated.totalCost);
+#ifdef CDFA_CERTIFICATE
+						//receiptInfo);// Only for CDFA certificate
+#else
+						ShmOCPP20Data->CostUpdated.totalCost);
+#endif /* CDFA_CERTIFICATE */
+
 	}
 
 	if(sqlite3_open(DB_FILE, &db))
@@ -1477,12 +1587,11 @@ int DB_Insert_Record(sqlite3 *db, int gun_index)
 	char receiptInfo[2048];
 
 	getReceiptInfo(gun_index, receiptInfo);
-	DEBUG_INFO("Receipt Info: %s\n", receiptInfo);
 
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 		sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) "
- 					    "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');",
+						"values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');",
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
 					    ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
@@ -1493,12 +1602,21 @@ int DB_Insert_Record(sqlite3 *db, int gun_index)
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
 					    ShmOCPP16Data->StopTransaction[gun_index].StopReason,
-					    ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+#ifdef CDFA_CERTIFICATE
+						receiptInfo);// Only for CDFA certificate
+#else
+						ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+#endif /* CDFA_CERTIFICATE */
+
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
 		sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) "
- 					    "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');",
+#ifdef CDFA_CERTIFICATE
+ 					    "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');",
+#else
+						"values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');",
+#endif /* CDFA_CERTIFICATE */
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
 					    ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
@@ -1509,7 +1627,13 @@ int DB_Insert_Record(sqlite3 *db, int gun_index)
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
 					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
 					    ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason,
-					    ShmOCPP20Data->CostUpdated.totalCost);
+#ifdef CDFA_CERTIFICATE
+						receiptInfo);// Only for CDFA certificate
+#else
+						ShmOCPP20Data->CostUpdated.totalCost);
+#endif /* CDFA_CERTIFICATE */
+
+
 	}
 	//DEBUG_INFO("sqlStr= %s\n", sqlStr);
 
@@ -1557,6 +1681,13 @@ int DB_Insert_Record(sqlite3 *db, int gun_index)
 		sqlite3_close(db);
 	}
 
+#ifdef CDFA_CERTIFICATE
+	// Only for CDFA certificate
+	sendReceiptMail((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime,
+					(char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime,
+					receiptInfo);
+#endif
+
 	return result;
 }
 
@@ -1637,7 +1768,6 @@ int DB_Get_Operactive(sqlite3 *db, uint8_t gun_index)
 	return result;
 }
 
-
 //======================================================
 // Peripheral initial
 //======================================================
@@ -4347,15 +4477,23 @@ int main(void)
 		ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status();
 
 		//==============================================
-		// Check task processing
+		// Period check for 10 seconds
 		//==============================================
-		if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
-			checkTask();
+		if(DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10000)
+		{
+			//==============================================
+			// Check task processing
+			//==============================================
+			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
+				checkTask();
 
-		//==============================================
-		// Check connection timeout specification
-		//==============================================
-		checkConnectionTimeout();
+			//==============================================
+			// Check connection timeout specification
+			//==============================================
+			checkConnectionTimeout();
+
+			ftime(&startTime[0][TMR_IDX_CHECK_TASK]);
+		}
 
 		//==============================================
 		// Something need run in Idle mode
@@ -4371,7 +4509,7 @@ int main(void)
 				{
 					setLedMotion(gun_index,LED_ACTION_INIT);
 				}
-				
+
 				sleep(5);
 				system("cd /root;./Module_FactoryConfig -m");
 				system("rm -f /Storage/OCPP/OCPPConfiguration");

+ 1 - 1
EVSE/Projects/AW-CCS/Apps/main.h

@@ -221,7 +221,7 @@ enum TIMER_IDX
 	TMR_IDX_POWERSAVING_RFID,
 	TMR_IDX_POWERSAVING_METER,
 	TMR_IDX_POWERSAVING_STATE_B,
-	TMR_IDX_11,
+	TMR_IDX_CHECK_TASK,
 	TMR_IDX_12,
 	TMR_IDX_13,
 	TMR_IDX_14,