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

2023-01-19 / Wendell

Actions
1. [mod] support dynamic relay control after generation 3
2. [add] alternate master at idle
3. [add] diagnostics of dispenser from web page
4. [mod] soft & hard reset logic
5. [add] add information to database(version column of reboot_record table)
6. [mod] psu control logic
7. [mod] ocpp stop reason
8. [add] ocpp authorize timeout
9. [mod] internal commucation logic
10.[mod] tilt sensor selftest logic
11.[mod] fix extend precharge timeout issue
12.[mod] capability logic
13.[add] fan policy
14.[fix] infy error summary logic
15.modify subVersion to 04

Files
1. As follow commit history

Image version : V2.05.XX.XXXX.XX
Wendell 2 жил өмнө
parent
commit
448b97d09d

+ 114 - 0
EVSE/Projects/DO360/Apps/Common.c

@@ -728,6 +728,120 @@ unsigned int getFileCrc32(char *filename)
     return result;
 }
 
+#define GUN_TYPE_QUANTITY           16
+bool IsAvalibleGunType(char name, unsigned char *type)
+{
+    // 20210817 remove type "R"
+    // 0: Chademo, 1: CCS, 2: GB
+    char         modelList[GUN_TYPE_QUANTITY] = {'J', 'U', 'V', 'E', 'F', 'G', 'T', 'D', 'K', 'P', 'S', 'Y', 'Z', 'I', 'Q', 'O'};
+    unsigned char typeList[GUN_TYPE_QUANTITY] = {  0,   1,   1,   1,   1,   2,   1,   1,   0,   1,   0,   1,   1,   1,   1,   0};
+
+    for(int i = 0; i < GUN_TYPE_QUANTITY; i++)
+    {
+        if(name == modelList[i])
+        {
+            *type = typeList[i];
+            return true;
+        }
+    }
+    return false;
+}
+
+// Input: _MainVer, _ModelName
+// Output: _FullVer
+void GetFullFirmwareVersion(char *_MainVer, char *_ModelName, char *_FullVer)
+{
+    int count = 0, chademo = 0, ccs = 0, gb = 0;
+    unsigned char _type = 0;
+
+    strcpy(_FullVer, _MainVer);
+    for(int idx = 0; idx < 3; idx++)
+    {
+        if(IsAvalibleGunType(_ModelName[7 + idx], &_type))
+        {
+            switch(_type)
+            {
+                // CHAdeMO
+                case 0:
+                    chademo++;
+                    count++;
+                    break;
+                // CCS
+                case 1:
+                    ccs++;
+                    count++;
+                    break;
+                // GBT
+                case 2:
+                    gb++;
+                    count++;
+                    break;
+            }
+        }
+    }
+
+    if(count == 1)
+    {
+        if(chademo > 0)
+        {
+            _FullVer[7] = '1';
+        }
+        else if(ccs > 0)
+        {
+            _FullVer[7] = '2';
+        }
+        else if(gb > 0)
+        {
+            _FullVer[7] = '3';
+        }
+    }
+    else
+    {
+        if(chademo > 0 && ccs > 0)
+        {
+            _FullVer[7] = '4';
+        }
+        else if(chademo > 0 && gb > 0)
+        {
+            _FullVer[7] = '5';
+        }
+        else if(ccs > 0 && gb > 0)
+        {
+            _FullVer[7] = '6';
+        }
+    }
+
+    // Get network option from model name
+    switch(_ModelName[10])
+    {
+        case 'B':
+        case 'U':
+            //Blue tooth
+            _FullVer[9] = '3';
+            break;
+        case 'W':
+            // WIFI
+            _FullVer[9] = '1';
+            break;
+        case 'T':
+            // 3G/4G
+            _FullVer[9] = '2';
+            break;
+        case 'D':
+            _FullVer[9] = '5';
+            break;
+        default:
+            // LAN
+            _FullVer[9] = '0';
+            break;
+    }
+    // Get rating power from model name
+    memcpy(&_FullVer[10], &_ModelName[4], 0x03);
+
+    // Get customer code
+    memcpy(&_FullVer[14], &_ModelName[12], 2);
+}
+
 //***************************************** No Use *****************************************
 float TariffParsing(char *StringItem, char *TariffCode)
 {

+ 3 - 0
EVSE/Projects/DO360/Apps/Common.h

@@ -9,6 +9,7 @@
 #define COMMON_H_
 
 #include <time.h>
+#include <stdbool.h>
 
 #define ARRAY_SIZE(A)               (sizeof(A) / sizeof(A[0]))
 #define PASS                        1
@@ -79,6 +80,8 @@ float TccDefaultPriceParsing(char *costString, float *price);
 
 unsigned short ParsingRatingPower(char *modelname);
 unsigned int getFileCrc32(char *filename);
+bool IsAvalibleGunType(char name, unsigned char *type);
+void GetFullFirmwareVersion(char *_MainVer, char *_ModelName, char *_FullVer);
 
 //***************************************** No Use *****************************************
 float TariffParsing(char *StringItem, char *TariffCode);

+ 50 - 13
EVSE/Projects/DO360/Apps/Config.h

@@ -71,6 +71,8 @@ typedef unsigned char               byte;
 #define ENABLE_PCBA_TEST            0
 
 #define PARALLEL_RELAY_COUNT        6
+#define GRAB_AT_START_CHARGING      0
+#define FAN_DUTY_OF_QUIET_MODE      35              // unit:1 %
 
 #define _PHIHONG_PRICE_SPLIT_KEY    ","
 #define _AUDI_PRICE_SPLIT_KEY       ";"
@@ -379,6 +381,15 @@ enum _CUSTOMER_CODE
     _CUSTOMER_CODE_Shell        = 5,
 };
 
+#define STR_FAN_AUTO_MODE           "Auto"
+#define STR_FAN_QUITE_MODE          "Quite"
+
+enum _FAN_CONTROL_POLICY
+{
+    _FAN_POLICY_AUTO_MODE               = 0x00,
+    _FAN_POLICY_QUITE_MODE              = 0x01,
+};
+
 #define STR_CABINET_ROLE_NONE       "Single"
 #define STR_CABINET_ROLE_MASTER     "Master"
 #define STR_CABINET_ROLE_SLAVE      "Slave"
@@ -713,12 +724,14 @@ typedef enum
 {
     _TILT_SENSOR_NONE           = 0,
     _TILT_SENSOR_WAIT           = 1,
-    _TILT_SENSOR_START          = 2,
-    _TILT_SENSOR_WAIT_RESPONSE  = 3,
-    _TILT_SENSOR_OUTCOME        = 4,
-    _TILT_SENSOR_STOP           = 5,
-    _TILT_SENSOR_WAIT_STOP      = 6,
-    _TILT_SENSOR_FINISH         = 7,
+    _TILT_SENSOR_STEP_1         = 2,
+    _TILT_SENSOR_WAIT_STEP_1    = 3,
+    _TILT_SENSOR_STEP_2         = 4,
+    _TILT_SENSOR_WAIT_STEP_2    = 5,
+    _TILT_SENSOR_OUTCOME        = 6,
+    _TILT_SENSOR_STOP           = 7,
+    _TILT_SENSOR_WAIT_STOP      = 8,
+    _TILT_SENSOR_FINISH         = 9,
 }_TILT_SENSOR_TEST_STEP;
 
 typedef union
@@ -916,12 +929,15 @@ typedef enum
     _GROLE_REQUEST_TO_CHARGING  = 30,
     _GROLE_TERMINATE            = 40,
     _GROLE_WAIT_TERMINATED      = 41,
+    _GROLE_DUMMY_MASTER         = 50,
+    _GROLE_DUMMY_FAULT          = 51,
+    _GROLE_NO_RESOURCE          = 90,
     _GROLE_NONE                 = 99,
 }_GROUP_ROLE;
 
 typedef union
 {
-    unsigned int CtrlValue[6];
+    unsigned int CtrlValue[7];
     struct
     {
         unsigned int IdleCtrlValue;
@@ -930,6 +946,7 @@ typedef union
         unsigned int DeratingCtrlValue;
         unsigned int ExtendCapabilityCtrlValue;
         unsigned int SlaveCtrlValue;
+        unsigned int DummyMasterCtrlValue;
     }RoleCtrl;
     struct
     {
@@ -956,7 +973,8 @@ typedef union
         unsigned int ReachMaxCurrentDemand:1;                   // 0: no effect,                1: reach ev max current demand
         unsigned int ReachMaxStageCurrent:1;                    // 0: no effect,                1: reach ev max stage current
         unsigned int SmoothDerating:1;                          // 0: no effect,                1: start smooth derating
-        unsigned int MasterCtrlRes:23;
+        unsigned int AlternateMasterStopRequest:1;              // 0: no effect,                1: alternate master need stop
+        unsigned int MasterCtrlRes:22;
 
         // StopChargingCtrlValue
         unsigned int StopChargingRequest:1;                     // 0: no effect,                1: master need to stop
@@ -992,9 +1010,24 @@ typedef union
         unsigned int SlaveChargingRequest:1;                    // 0: no effect,                1: request slave to charging after power off
         unsigned int CheckSlaveReady:1;                         // 0: no effect,                1: check if slave is ready
         unsigned int WaitSlaveReady:1;                          // 0: no effect,                1: wait slave is ready
+        unsigned int WaitDummyMaster:1;                         // 0: no effect,                1: wait dummy master stop
         unsigned int SlavePowerOffRequest:1;                    // 0: no effect,                1: request slave to power off
         unsigned int SlavePowerOffConfirmed:1;                  // 0: no effect,                1: slave power off confirmed
-        unsigned int SlaveCtrlRes:27;
+        unsigned int SlaveCtrlRes:26;
+
+        // DummyMasterCtrlValue
+        unsigned int DummyMasterRequest:1;                      // 0: no effect,                1: dummy master request process start
+        unsigned int DummyMasterReqConfirmed:1;                 // 0: no effect,                1: dummy master request process confirmed
+        unsigned int DummyMasterPermission:1;                   // 0: no effect,                1: dummy master permission
+        unsigned int DummyMasterGrabCheck:1;                    // 0: no effect,                1: dummy master grab check
+        unsigned int DummyMasterWait:1;                         // 0: no effect,                1: wait dummy master ready
+        unsigned int DummyMasterReady:1;                        // 0: no effect,                1: dummy master ready
+        unsigned int DummyMasterFindPartner:1;                  // 0: no effect,                1: find dummy master
+        unsigned int DummyMasterRelayOn:1;                      // 0: no effect,                1: set dummy master parallel relay on
+        unsigned int DummyMasterRelayConfirmed:1;               // 0: no effect,                1: dummy master parallel relay confirmed
+        unsigned int DummyMasterCompleted:1;                    // 0: no effect,                1: dummy master process is completed
+        unsigned int DummyMasterFault:1;                        // 0: no effect,                1: dummy master request fault
+        unsigned int DummyMasterCtrlRes:21;
     }bits;
 }PsuGroupControl;
 
@@ -1024,7 +1057,7 @@ typedef struct
     unsigned char           TargetGroup;                        // target group index + 1
     unsigned char           ReservedTarget;                     // reserved target group index + 1
     unsigned char           SmoothDeratingTarget;               // group index + 1
-    unsigned char           res;                                // reserved
+    unsigned char           AlternateMaster;                    // alternate target group index + 1
     PsuGroupControl         GroupCtrl;
     unsigned short          ReAssignAvailableCurrent;           // group available current when reassign, unit: 0.1A
     unsigned short          ParallelCheck;
@@ -1469,16 +1502,18 @@ typedef struct
     unsigned char Status;
 }ConnectorConfigAndStatus;
 
+#define MAX_GUN_ERROR_QUANTITY          5
+
 typedef union
 {
     unsigned int ErrorValue;
     struct
     {
-        unsigned int OutputRelayWelding:1;              // 0: no effect,    1: Welding
-        unsigned int OutputRelayDrivingFault:1;         // 0: no effect,    1: DrivingFault
+        unsigned int PsuGroupNoResource:1;              // 0: no effect,    1: psu group all alarm or fault >> group no resource
         unsigned int ParallelRelayWelding:1;            // 0: no effect,    1: Welding
         unsigned int ParallelRelayDrivingFault:1;       // 0: no effect,    1: DrivingFault
-        unsigned int PsuGroupNoResource:1;              // 0: no effect,    1: psu group all alarm or fault >> group no resource
+        unsigned int OutputRelayWelding:1;              // 0: no effect,    1: Welding
+        unsigned int OutputRelayDrivingFault:1;         // 0: no effect,    1: DrivingFault
         unsigned int res:27;
     }bits;
 }GunErrorFlag;
@@ -1515,6 +1550,8 @@ typedef struct
     int GunLimitPower[MAX_GUN_QUANTITY];                // unit: 0.1kW
     int GunLimitVoltage[MAX_GUN_QUANTITY];              // unit: 0.1V
     int GunLimitCurrent[MAX_GUN_QUANTITY];              // unit: 0.1A
+
+    int IndividualLimit[MAX_GUN_QUANTITY];
 }OutputLimitation;
 
 typedef enum

+ 13 - 13
EVSE/Projects/DO360/Apps/InfyGroup_PsuCommObj.c

@@ -7,11 +7,11 @@
 
 #include "InfyGroup_PsuCommObj.h"
 
-#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
-#define NO		0
-#define YES		1
+#define ARRAY_SIZE(A)                   (sizeof(A) / sizeof(A[0]))
+#define NO                              0
+#define YES                             1
 
-#define DEBUG_LIB						1
+#define DEBUG_LIB                       1
 
 void PRINTF_LIB_FUNC(char *string, ...);
 float IEEE_754_to_float(const byte raw[4]);
@@ -21,16 +21,16 @@ float IEEE_754_to_float(const byte raw[4]);
 //================================================
 void PRINTF_LIB_FUNC(char *string, ...)
 {
-	if (DEBUG_LIB)
-	{
-		va_list args;
-		char buffer[4096];
+    if (DEBUG_LIB)
+    {
+        va_list args;
+        char buffer[4096];
 
-		va_start(args, string);
-		vsnprintf(buffer, sizeof(buffer), string, args);
-		va_end(args);
-		printf("%s \n", buffer);
-	}
+        va_start(args, string);
+        vsnprintf(buffer, sizeof(buffer), string, args);
+        va_end(args);
+        printf("%s \n", buffer);
+    }
 }
 
 float IEEE_754_to_float(const byte raw[4])

+ 29 - 2
EVSE/Projects/DO360/Apps/Module_Authorize.c

@@ -348,6 +348,31 @@ void Get_Ocpp_EVCCID_Prefix(char *prefix)
     strcpy(prefix, "");
 }
 
+//===============================================
+// Ocpp AuthorizeTimeout
+//===============================================
+int Get_Ocpp_AuthorizeTimeout(void)
+{
+    int timeout = AUTHORIZE_WAIT_OCPP_TIMEOUT;
+
+    if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+    {
+        if(strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData, "") != 0)
+        {
+            timeout = atoi((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData);
+        }
+    }
+    if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+    {
+        if(strcmp((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variableAttribute[0].value, "") != 0)
+        {
+            timeout = atoi((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variableAttribute[0].value);
+        }
+
+    }
+    return timeout;
+}
+
 void SetAuthorize(AuthorizingInfoData *AuthInfo, unsigned char type)
 {
     if(AuthInfo->AuthIdType == _Type_MacAddress)
@@ -594,6 +619,7 @@ int main(void)
 {
     int _dispenser = 0, _connector = 0;
     unsigned char _authResult = _AuthResult_None;
+    int _AuthorizeTimeout = 0;
 
     bool _autoSelection = false;
     bool _needOcppAuthorize = false;
@@ -717,12 +743,13 @@ int main(void)
             case _AuthorizeStatus_Busy:
                 if(_preSysAuthStatus != ShmSysConfigAndInfo->SysInfo.AuthorizedStatus)
                 {
-                    AUTH_INFO("[SysAuthStatus Busy]");
+                    _AuthorizeTimeout = Get_Ocpp_AuthorizeTimeout();
+                    AUTH_INFO("[SysAuthStatus Busy] AuthorizeTimeout %d(s)", _AuthorizeTimeout);
                     _preSysAuthStatus = ShmSysConfigAndInfo->SysInfo.AuthorizedStatus;
                     GetClockTime(&_SysAuth_Time);
                 }
 
-                if(GetTimeoutValue(_SysAuth_Time) / uSEC_VAL >= AUTHORIZE_WAIT_OCPP_TIMEOUT)
+                if(GetTimeoutValue(_SysAuth_Time) / uSEC_VAL >= _AuthorizeTimeout)
                 {
                     AUTH_INFO("*********** Ocpp Authorizing Timeout ***********");
                     _authResult = _AuthResult_Invalid;

+ 1 - 18
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -857,23 +857,6 @@ void tcpSocketClientStart(void)
 
 //--------------------------------------------Socket Client End--------------------------------------------
 
-BOOL IsAvalibleGunType(char name, unsigned char *type)
-{
-    // 20210817 remove type "R"
-	char         modelList[10] = {'J', 'U', 'V', 'E', 'F', 'G', 'T', 'D', 'K', 'P'};
-	unsigned char typeList[10] = {  0,   1,   1,   1,   1,   2,   1,   1,   0,   1}; // 0 : Chademo, 1: CCS, 2: GB
-
-	for(int i = 0; i < 11; i++)
-	{
-		if(name == modelList[i])
-		{
-			*type = typeList[i];
-			return true;
-		}
-	}
-	return false;
-}
-
 unsigned char ConnectorQuantityTypeParsing(unsigned char *modelName, unsigned char *type, unsigned char *physical, unsigned char *safety)
 {
 	unsigned char quantity = 0;
@@ -3107,7 +3090,7 @@ BOOL DispenserStatusCodeHandler(struct PACKET_STRUCTURE *packet, unsigned char d
 		}
 */
 		char strDispenserStatus[128];
-		sprintf(strDispenserStatus, "Dispenser id %d, Status Code Len: %d", packet->Header.id, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount);
+		sprintf(strDispenserStatus, "Dispenser %d, Status Code Len: %d", dispenserIndex + 1, ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount);
 		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount > 0)
 		{
 		    for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].WarningInfo.WarningCount; i++)

+ 46 - 54
EVSE/Projects/DO360/Apps/Module_InternalComm.c

@@ -222,7 +222,7 @@ unsigned short MaxValue(unsigned short value1, unsigned short value2)
 //==========================================
 void GetFwAndHwVersion_Fan()
 {
-	if(Query_FW_Ver(Uart5Fd, Addr.Fan, &ver) == PASS)
+	if(Query_FW_Ver(Uart5Fd, Addr.Fan, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// FanModuleData
 		strcpy((char *) ShmFanModuleData->version, ver.Version_FW);
@@ -231,7 +231,7 @@ void GetFwAndHwVersion_Fan()
 		LOG_INFO("GetFwAndHwVersion_Fan s1 = %s", ver.Version_FW);
 	}
 
-	if (Query_HW_Ver(Uart5Fd, Addr.Fan, &ver) == PASS)
+	if (Query_HW_Ver(Uart5Fd, Addr.Fan, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, ver.Version_FW);
@@ -241,7 +241,7 @@ void GetFwAndHwVersion_Fan()
 
 void GetFwAndHwVersion_Relay()
 {
-	if (Query_FW_Ver(Uart5Fd, Addr.DO360_RC1, &ver) == PASS)
+	if (Query_FW_Ver(Uart5Fd, Addr.DO360_RC1, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// RelayModuleData
 		strcpy((char *) ShmRelayModuleData[0]->version, ver.Version_FW);
@@ -250,7 +250,7 @@ void GetFwAndHwVersion_Relay()
 		LOG_INFO("GetFwAndHwVersion_RC1 s1 = %s", ver.Version_FW);
 	}
 
-	if (Query_HW_Ver(Uart5Fd, Addr.DO360_RC1, &ver) == PASS)
+	if (Query_HW_Ver(Uart5Fd, Addr.DO360_RC1, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, ver.Version_FW);
@@ -261,7 +261,7 @@ void GetFwAndHwVersion_Relay()
 void GetFwAndHwVersion_Relay2()
 {
 	// DO360 RC2
-	if (Query_FW_Ver(Uart5Fd, Addr.DO360_RC2, &ver) == PASS)
+	if (Query_FW_Ver(Uart5Fd, Addr.DO360_RC2, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// RelayModuleData
 		strcpy((char *) ShmRelayModuleData[1]->version, ver.Version_FW);
@@ -270,7 +270,7 @@ void GetFwAndHwVersion_Relay2()
 		LOG_INFO("GetFwAndHwVersion_RC2 s1 = %s", ver.Version_FW);
 	}
 
-	if (Query_HW_Ver(Uart5Fd, Addr.DO360_RC2, &ver) == PASS)
+	if (Query_HW_Ver(Uart5Fd, Addr.DO360_RC2, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.Relay2ModuleHwRev, ver.Version_FW);
@@ -280,7 +280,7 @@ void GetFwAndHwVersion_Relay2()
 
 void GetFwAndHwVersion_Led()
 {
-	if (Query_FW_Ver(Uart5Fd, Addr.Led, &ver) == PASS)
+	if (Query_FW_Ver(Uart5Fd, Addr.Led, &ver, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		// LedModuleData
 		strcpy((char *) ShmLedModuleData->version, ver.Version_FW);
@@ -302,24 +302,6 @@ void GetFwAndHwVersion_Led()
 //	}
 }
 
-void GetFwVersion_AC()
-{
-	if (Query_FW_Ver(Uart5Fd, Addr.AcPlug, &ver) == PASS)
-	{
-		ac_chargingInfo[0]->SelfTest_Comp = YES;
-		strcpy((char *) ac_chargingInfo[0]->version, ver.Version_FW);
-	}
-}
-
-void GetAcModelName()
-{
-	memset(ShmSysConfigAndInfo->SysConfig.AcModelName, 0x00, sizeof(ShmSysConfigAndInfo->SysConfig.AcModelName));
-	if (Query_Model_Name(Uart5Fd, Addr.AcPlug, ShmSysConfigAndInfo->SysConfig.AcModelName) == PASS)
-	{
-		LOG_INFO("ac model name = %s", ShmSysConfigAndInfo->SysConfig.AcModelName);
-	}
-}
-
 void SetRtcData_Relay(unsigned char index)
 {
 	struct timeb csuTime;
@@ -353,14 +335,14 @@ void SetRtcData_Relay(unsigned char index)
 
 	if(index == 0)
 	{
-		if (Config_Rtc_Data(Uart5Fd, Addr.DO360_RC1, &rtc) == PASS)
+		if (Config_Rtc_Data(Uart5Fd, Addr.DO360_RC1, &rtc, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 		{
 			//LOG_INFO("SetRtc (RB) sucessfully.");
 		}
 	}
 	else
 	{
-		if (Config_Rtc_Data(Uart5Fd, Addr.DO360_RC2, &rtc) == PASS)
+		if (Config_Rtc_Data(Uart5Fd, Addr.DO360_RC2, &rtc, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 		{
 			//LOG_INFO("SetRtc (RB) sucessfully.");
 		}
@@ -398,7 +380,7 @@ void SetRtcData_Fan()
 	rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
 	rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
 
-	if (Config_Rtc_Data(Uart5Fd, Addr.Fan, &rtc) == PASS)
+	if (Config_Rtc_Data(Uart5Fd, Addr.Fan, &rtc, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		//LOG_INFO("SetRtc (FB) sucessfully.");
 	}
@@ -406,7 +388,7 @@ void SetRtcData_Fan()
 
 void SetModelName_Fan()
 {
-	if (Config_Model_Name(Uart5Fd, Addr.Fan, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS)
+	if (Config_Model_Name(Uart5Fd, Addr.Fan, ShmSysConfigAndInfo->SysConfig.ModelName, 14, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		LOG_INFO("Set Model name PASS = %s", ShmSysConfigAndInfo->SysConfig.ModelName);
 	}
@@ -417,7 +399,7 @@ void GetPresentInputVol()
 {
     if(ShmChargerInfo->Control.RelayCtrl.bits.AcInputDisable == YES)
     {
-        if(Query_DC_InputVoltage(Uart5Fd, Addr.DO360_RC1, &dcInputVoltage) == PASS)
+        if(Query_DC_InputVoltage(Uart5Fd, Addr.DO360_RC1, &dcInputVoltage, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             ShmSysConfigAndInfo->SysInfo.InputVoltageDc = dcInputVoltage.DC_Input_1;
 
@@ -478,7 +460,7 @@ void GetPresentInputVol()
     }
     else
     {
-        if (Query_Present_InputVoltage(Uart5Fd, Addr.DO360_RC1, &inputVoltage) == PASS)
+        if (Query_Present_InputVoltage(Uart5Fd, Addr.DO360_RC1, &inputVoltage, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             // resolution : 0.1
             ShmSysConfigAndInfo->SysInfo.InputVoltageR = ShmRelayModuleData[0]->InputL1Volt = inputVoltage.L1N_L12;
@@ -747,7 +729,7 @@ void GetPersentOutputVol()
     if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
     {
         // two relay board
-        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC1, &outputVoltage) == PASS)
+        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC1, &outputVoltage, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             ShmRelayModuleData[0]->Gun1FuseOutputVolt = outputVoltage.behindFuse_Voltage_C1;
             ShmRelayModuleData[0]->Gun1RelayOutputVolt = outputVoltage.behindRelay_Voltage_C1;
@@ -761,7 +743,7 @@ void GetPersentOutputVol()
         }
 
         // DO360 RC2
-        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC2, &outputVoltage) == PASS)
+        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC2, &outputVoltage, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             ShmRelayModuleData[1]->Gun1FuseOutputVolt = outputVoltage.behindFuse_Voltage_C1;
             ShmRelayModuleData[1]->Gun1RelayOutputVolt = outputVoltage.behindRelay_Voltage_C1;
@@ -777,7 +759,7 @@ void GetPersentOutputVol()
     else
     {
         // only one relay board
-        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC1, &outputVoltage) == PASS)
+        if (Query_Present_OutputVoltage(Uart5Fd, Addr.DO360_RC1, &outputVoltage, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             ShmRelayModuleData[0]->Gun1FuseOutputVolt = outputVoltage.behindFuse_Voltage_C1;
             ShmRelayModuleData[0]->Gun1RelayOutputVolt = outputVoltage.behindRelay_Voltage_C1;
@@ -796,7 +778,7 @@ void GetPersentOutputVol()
 void GetFanSpeed()
 {
 	//LOG_INFO("Get fan board speed");
-	if (Query_Fan_Speed(Uart5Fd, Addr.Fan, &fanSpeed) == PASS)
+	if (Query_Fan_Speed(Uart5Fd, Addr.Fan, &fanSpeed, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 		ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0];
 		ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1];
@@ -816,13 +798,13 @@ void GetRelayOutputStatus(void)
 {
     unsigned char location = 0;
 
-    if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC1, &regRelay[0]) == PASS)
+    if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC1, &regRelay[0], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
     {
         regRelay[0].relay_event.bits.AC_Contactor = outputRelay[0].relay_event.bits.AC_Contactor;
     }
     if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
     {
-        if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC2, &regRelay[1]) == PASS)
+        if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC2, &regRelay[1], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
             regRelay[1].relay_event.bits.AC_Contactor = outputRelay[1].relay_event.bits.AC_Contactor;
         }
@@ -953,7 +935,7 @@ void GetGfdAdc(void)
         // define : 每 0.2 ~ 1 秒一次
         // occur : <= 75k 歐姆 @ 150 - 750 Vdc
         // warning : >= 100 歐姆 && <= 500 歐姆 @ 150-750 Vdc
-        if(Query_Gfd_Adc(Uart5Fd, Addr.DO360_RC1, &gfd_adc[0]) == PASS)
+        if(Query_Gfd_Adc(Uart5Fd, Addr.DO360_RC1, &gfd_adc[0], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
         {
 //            if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[0].Parameter.bits.GfdDetection ||
 //                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[1].Parameter.bits.GfdDetection)
@@ -971,7 +953,7 @@ void GetGfdAdc(void)
 //        }
         if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
         {
-            if(Query_Gfd_Adc(Uart5Fd, Addr.DO360_RC2, &gfd_adc[1]) == PASS)
+            if(Query_Gfd_Adc(Uart5Fd, Addr.DO360_RC2, &gfd_adc[1], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
             {
 
             }
@@ -1010,20 +992,19 @@ void SetFanModuleSpeed()
 		FanSpeed _fanSpeed;
 
 		_setFanSpeed += fanSpeedSmoothValue;
-
-		if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
+		if(_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
+		{
 			_setFanSpeed = ShmFanModuleData->SetFan1Speed;
+		}
 
-		//printf("_setFanSpeed = %d \n", _setFanSpeed);
 		_fanSpeed.speed[0] = _setFanSpeed;
-
 		_fanSpeed.speed[1] = _setFanSpeed;
-
 		_fanSpeed.speed[2] = _setFanSpeed;
-
 		_fanSpeed.speed[3] = _setFanSpeed;
 
-		if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed) == PASS)
+		ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
+
+		if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 		{
 			//LOG_INFO("successfully Fan");
 		}
@@ -1380,7 +1361,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
 
 	if (_checkLedChanged > 0)
 	{
-		if (Config_Led_Color(Uart5Fd, Addr.Led, &led_color) == PASS)
+		if (Config_Led_Color(Uart5Fd, Addr.Led, &led_color, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 		{
 			_checkLedChanged--;
 
@@ -1826,7 +1807,7 @@ void SetGfdConfig(byte index, byte resister)
 	add = index < 2 ? Addr.DO360_RC1 : Addr.DO360_RC2;
 
 	//LOG_INFO("************************GFD Vol = %d, GFD Res = %d", gfd_config.reqVol, gfd_config.resister);
-	if (Config_Gfd_Value(Uart5Fd, add, &gfd_config) == PASS)
+	if (Config_Gfd_Value(Uart5Fd, add, &gfd_config, ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) == PASS)
 	{
 //		LOG_INFO("Set reqVol = %f, resister = %d",
 //				gfd_config.reqVol,
@@ -2031,7 +2012,18 @@ void GetFanSpeedByFunction()
 	if (temp > 70)
 		_temp_diff = temp - 70;
 
-	ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED;
+	double _duty = 0;
+	_duty = ((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100;
+
+	if(ShmSysConfigAndInfo->SysConfig.FanControlPolicy != _FAN_POLICY_AUTO_MODE)
+	{
+	    if(_duty > FAN_DUTY_OF_QUIET_MODE)
+	    {
+	        _duty = FAN_DUTY_OF_QUIET_MODE;
+	    }
+	}
+
+	ShmFanModuleData->TestFanSpeed = _duty * MAX_FAN_SPEED;
 
 	if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED)
 		ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
@@ -2087,7 +2079,7 @@ int main(void)
     {
         if(ShmRelayModuleData[0]->SelfTest_Comp == NO)
         {
-            if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]) != PASS)
+            if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) != PASS)
                 LOG_INFO("Config_Relay1_Output fail");
         }
         else
@@ -2102,7 +2094,7 @@ int main(void)
         {
             if(ShmRelayModuleData[1]->SelfTest_Comp == NO)
             {
-                if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]) != PASS)
+                if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm) != PASS)
                     LOG_INFO("Config_Relay2_Output fail");
             }
             else
@@ -2260,7 +2252,7 @@ int main(void)
                 // 搭上/鬆開 Relay
                 if(IsNoneMatchRelayStatus(0))
                 {
-                    if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]))
+                    if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm))
                     {
                         //regRelay[0].relay_event.relay_status[0] = outputRelay[0].relay_event.relay_status[0];
                         //regRelay[0].relay_event.relay_status[1] = outputRelay[0].relay_event.relay_status[1];
@@ -2279,7 +2271,7 @@ int main(void)
                     // 搭上/鬆開 Relay
                     if(IsNoneMatchRelayStatus(1))
                     {
-                        if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]))
+                        if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1], ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm))
                         {
                             //regRelay[1].relay_event.relay_status[0] = outputRelay[1].relay_event.relay_status[0];
                             //regRelay[1].relay_event.relay_status[1] = outputRelay[1].relay_event.relay_status[1];
@@ -2305,7 +2297,7 @@ int main(void)
                 {
                     GetFanSpeedByFunction();
                     GetFanSpeed();
-                    ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
+
                     GetClockTime(&_priority_time);
 
                     unsigned short TargetSpeed = ShmFanModuleData->TestFanSpeed;

+ 29 - 10
EVSE/Projects/DO360/Apps/Module_PrimaryComm.c

@@ -35,8 +35,8 @@
 
 #define COMM_FAIL_COUNT             10
 #define STATE_CHANGE_COUNT          3
-#define TILT_SENSOR_WAIT_TIME       1               // unit: 1s
-#define TILT_SENSOR_WAIT_RESPONSE   1               // unit: 1s
+#define TILT_SENSOR_WAIT_TIME       500             // unit: 1ms
+#define TILT_SENSOR_WAIT_RESPONSE   500             // unit: 1ms
 #define TILT_SENSOR_WAIT_STOP       1               // unit: 1s
 
 typedef unsigned char 		byte;
@@ -514,28 +514,47 @@ void CheckTiltSensor(void)
                     preTiltSensorStep = step;
                     GetClockTime(&_tiltSensor_time);
                 }
-                if((GetTimeoutValue(_tiltSensor_time) / uSEC_VAL) > TILT_SENSOR_WAIT_TIME)
+                if((GetTimeoutValue(_tiltSensor_time) / mSEC_VAL) > TILT_SENSOR_WAIT_TIME)
                 {
-                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_START;
+                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_STEP_1;
                 }
                 break;
-            case _TILT_SENSOR_START:
+            case _TILT_SENSOR_STEP_1:
                 if(preTiltSensorStep != step)
                 {
                     preTiltSensorStep = step;
-                    LOG_INFO("Tilt sensor self test start!");
+                    LOG_INFO("Tilt sensor self test: step 1");
                 }
-                ShmPrimaryMcuData->OutputDrv.bits.SystemLed3Drv = true;
                 ShmPrimaryMcuData->OutputDrv.bits.SystemLed4Drv = true;
-                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT_RESPONSE;
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT_STEP_1;
+                break;
+            case _TILT_SENSOR_WAIT_STEP_1:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    GetClockTime(&_tiltSensor_time);
+                }
+                if((GetTimeoutValue(_tiltSensor_time) / mSEC_VAL) > TILT_SENSOR_WAIT_RESPONSE)
+                {
+                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_STEP_2;
+                }
+                break;
+            case _TILT_SENSOR_STEP_2:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    LOG_INFO("Tilt sensor self test: step 2");
+                }
+                ShmPrimaryMcuData->OutputDrv.bits.SystemLed3Drv = true;
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT_STEP_2;
                 break;
-            case _TILT_SENSOR_WAIT_RESPONSE:
+            case _TILT_SENSOR_WAIT_STEP_2:
                 if(preTiltSensorStep != step)
                 {
                     preTiltSensorStep = step;
                     GetClockTime(&_tiltSensor_time);
                 }
-                if((GetTimeoutValue(_tiltSensor_time) / uSEC_VAL) > TILT_SENSOR_WAIT_RESPONSE)
+                if((GetTimeoutValue(_tiltSensor_time) / mSEC_VAL) > TILT_SENSOR_WAIT_RESPONSE)
                 {
                     ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_OUTCOME;
                 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 636 - 52
EVSE/Projects/DO360/Apps/Module_PsuComm.c


BIN
EVSE/Projects/DO360/Apps/Module_PsuComm_PH


+ 4 - 4
EVSE/Projects/DO360/Apps/PhGroup_PsuCommObj.c

@@ -7,11 +7,11 @@
 
 #include "PhGroup_PsuCommObj.h"
 
-#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
-#define NO		0
-#define YES		1
+#define ARRAY_SIZE(A)                   (sizeof(A) / sizeof(A[0]))
+#define NO                              0
+#define YES                             1
 
-#define DEBUG_LIB						1
+#define DEBUG_LIB                       1
 
 void PRINTF_LIB_FUNC(char *string, ...);
 float IEEE_754_to_float(const byte raw[4]);

+ 0 - 3
EVSE/Projects/DO360/Apps/PhGroup_PsuCommObj.h

@@ -65,9 +65,6 @@ typedef unsigned int        unit;
 int                         CanFd;
 pid_t                       recFork;
 
-extern bool g_GetModuleCap;
-
-
 typedef union
 {
 	unsigned int PwrMessage;

+ 344 - 106
EVSE/Projects/DO360/Apps/ReadCmdline.c

@@ -706,12 +706,11 @@ void RunSelfProc()
 	printf("self test status = %x\n", ShmSysConfigAndInfo->SysInfo.SelfTestSeq);
 }
 
-void ShowFwVer(void)
+void ShowCabinetVer(void)
 {
-    printf("\r\nPower Cabinet, Model Name: %s, SN: %s", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber);
-    printf("\r\n  Csu Bootload: %s", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev);
-    //printf("\r\n    Csu Kernel: %s", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev);
-    printf("\r\n    Csu Kernel: ");
+    printf("Power Cabinet, Model Name: %s, SN: %s\r\n", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber);
+    printf("  Csu Bootload: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev);
+    printf("    Csu Kernel: ");
     for(int i = 0; i < strlen((char *)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev); i++)
     {
         if(ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev[i] != '\r' && ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev[i] != '\n')
@@ -719,40 +718,109 @@ void ShowFwVer(void)
             printf("%c", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev[i]);
         }
     }
-    printf("\r\n   Csu Root Fs: %s [%s]", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, ShmChargerInfo->SysMisc.SubVersion);
-    printf("\r\n   Csu Primary: %s", ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev);
-    printf("\r\n    Fan Module: %s", ShmSysConfigAndInfo->SysInfo.FanModuleFwRev);
-    printf("\r\n Relay1 Module: %s", ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev);
-    printf("\r\n Relay2 Module: %s", ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev);
+    printf("\r\n");
+    printf("   Csu Root Fs: %s [%s]\r\n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, ShmChargerInfo->SysMisc.SubVersion);
+    printf("   Csu Primary: %s\r\n", ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev);
+    printf("    Fan Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.FanModuleFwRev);
+    printf(" Relay1 Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev);
+    printf(" Relay2 Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev);
+}
 
+void ShowDispenserVer(int DispenserIndex)
+{
+    printf("Dispenser %d Status: %d", DispenserIndex + 1, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].LocalStatus);
+    if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].LocalStatus != _DS_None &&
+        ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].LocalStatus != _DS_Timeout)
+    {
+        printf(", Model Name: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].ModelName);
+        printf("  Csu Bootload: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuBootLoadFwRev);
+        printf("    Csu Kernel: ");
+        for(int i = 0; i < strlen((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuKernelFwRev); i++)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuKernelFwRev[i] != '\r' &&
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuKernelFwRev[i] != '\n')
+            {
+                printf("%c", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuKernelFwRev[i]);
+            }
+        }
+        printf("\r\n");
+        printf("   Csu Root Fs: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuRootFsFwRev);
+        printf("   Csu Primary: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].CsuPrimFwRev);
+        printf("    Fan Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].FanModuleFwRev);
+        printf("  Relay Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].RelayModuleFwRev);
+        printf("   Connector 1: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].Connector1FwRev);
+        printf("   Connector 2: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].Connector2FwRev);
+        printf("    Led Module: %s\r\n", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].LedModuleFwRev);
+    }
+    else
+    {
+        printf("\r\n");
+    }
+}
+
+void ShowAllVer(void)
+{
+    ShowCabinetVer();
+    printf("\r\n");
     for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity; i++)
     {
-        printf("\r\n\r\nDispenser[%d] Status: %d", i, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].LocalStatus);
-        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].LocalStatus != _DS_None &&
-            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].LocalStatus != _DS_Timeout)
+        ShowDispenserVer(i);
+        printf("\r\n");
+    }
+}
+
+void ShowFwVer(char *inputCmd, unsigned int opt)
+{
+    int totalCnt = 0, maxPara = 0, dispenser = 0;
+
+    maxPara = 2;
+    totalCnt = GetSubCommand(inputCmd);
+
+    printf("\r\n");
+    if(totalCnt > maxPara)
+    {
+        printf("Input cmd fail ------  ver [all | cabinet | dispenser] [...]\r\n\r\n");
+        return;
+    }
+
+    if(totalCnt == 0)
+    {
+        ShowAllVer();
+        return;
+    }
+    else if(totalCnt == 1)
+    {
+        if(strcmp(&MultiSubCmd[0][0], "all") == 0)
+        {
+            ShowAllVer();
+            return;
+        }
+        else if(strcmp(&MultiSubCmd[0][0], "cabinet") == 0)
+        {
+            ShowCabinetVer();
+            printf("\r\n");
+            return;
+        }
+    }
+    else if(totalCnt == 2)
+    {
+        dispenser = atoi(&MultiSubCmd[1][0]);
+        if(strcmp(&MultiSubCmd[0][0], "dispenser") == 0)
         {
-            printf(", Model Name: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ModelName);
-            printf("\r\n  Csu Bootload: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuBootLoadFwRev);
-            //printf("\r\n   Csu Kernel: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuKernelFwRev);
-            printf("\r\n    Csu Kernel: ");
-            for(int j = 0; j < strlen((char *)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuKernelFwRev); j++)
+            if(dispenser > 0 && dispenser <= MAX_DISPENSER_QUANTITY)
             {
-                if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuKernelFwRev[j] != '\r' &&
-                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuKernelFwRev[j] != '\n')
-                {
-                    printf("%c", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuKernelFwRev[j]);
-                }
+                ShowDispenserVer(dispenser - 1);
+                printf("\r\n");
+                return;
             }
-            printf("\r\n   Csu Root Fs: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuRootFsFwRev);
-            printf("\r\n   Csu Primary: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].CsuPrimFwRev);
-            printf("\r\n    Fan Module: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].FanModuleFwRev);
-            printf("\r\n  Relay Module: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].RelayModuleFwRev);
-            printf("\r\n   Connector 1: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Connector1FwRev);
-            printf("\r\n   Connector 2: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Connector2FwRev);
-            printf("\r\n    Led Module: %s", ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].LedModuleFwRev);
+            printf("Input cmd fail ------  ver [dispenser] [id 1-%d]\r\n\r\n", MAX_DISPENSER_QUANTITY);
+            return;
         }
+        printf("Input cmd fail ------  ver [dispenser] [id]\r\n\r\n");
+        return;
     }
-    printf("\r\n\r\n");
+
+    printf("Input cmd fail ------  ver [all | cabinet | dispenser] [...]\r\n\r\n");
 }
 
 void GetFwVerProc(char *v1)
@@ -955,7 +1023,7 @@ void SerialNumberCmd(char *inputCmd, unsigned int opt)
 
     printf("\r\n");
 
-    if(totalCnt != maxPara)
+    if(totalCnt != maxPara || strcmp(&MultiSubCmd[0][0], "set") != EQUAL)
     {
         printf("Input cmd fail ------  model [set] [serial number]\r\n\r\n");
         return;
@@ -976,15 +1044,6 @@ void SetFanSpeed(char *v1)
 	ShmFanModuleData->TestFanSpeed = speed;
 }
 
-void GetFanSpeed()
-{
-    printf("Target Speed = %d \n", ShmFanModuleData->TestFanSpeed);
-	printf("ShmFanModuleData->PresentFan1Speed = %d \n", ShmFanModuleData->PresentFan1Speed);
-	printf("ShmFanModuleData->PresentFan2Speed = %d \n", ShmFanModuleData->PresentFan2Speed);
-	printf("ShmFanModuleData->PresentFan3Speed = %d \n", ShmFanModuleData->PresentFan3Speed);
-	printf("ShmFanModuleData->PresentFan4Speed = %d \n", ShmFanModuleData->PresentFan4Speed);
-}
-
 void SetDebugMode(char *v1)
 {
 	int mode = atoi(v1);
@@ -1341,43 +1400,93 @@ void RemoveGroupCollection(byte group, byte target)
     }
 }
 
-// Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay
-//  1   (00)   00  3     00    [00] [00] [00]    0000 V     0000 A    0000 kW    0000 A   0000 A   00      XX
-void ShowGroupingInfo(void)
+int ShowSingleGroupingInfo(int gun)
 {
-    byte target = 0;
+    printf("  %d   (%2d)   %2d  %d     %02X    ",
+        gun + 1, _chargingData[gun]->SystemStatus, ShmChargerInfo->PsuGrouping.GroupCollection[gun].Role,
+        ShmChargerInfo->PsuGrouping.GroupCollection[gun].Partner.Quantity, ShmChargerInfo->PsuGrouping.GroupCollection[gun].TargetGroup);
 
-    printf("\r\n Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay");
+    for(int j = 0; j < 3; j++)
+    {
+        if(ShmChargerInfo->PsuGrouping.GroupCollection[gun].Role == 1 && j < ShmChargerInfo->PsuGrouping.GroupCollection[gun].Partner.Quantity)
+        {
+            printf("[%02X] ", ShmChargerInfo->PsuGrouping.GroupCollection[gun].Partner.Member[j]);
+        }
+        else
+        {
+            printf("     ");
+        }
+    }
+    printf("   %4d V     %4d A    %4d kW    %4d A   %4d A   ",
+        (int)_chargingData[gun]->PresentChargingVoltage, (int)_chargingData[gun]->PresentChargingCurrent,
+        (int)(_chargingData[gun]->AvailableChargingPower / 10), (int)(_chargingData[gun]->AvailableChargingCurrent / 10),
+        (int)(_chargingData[gun]->DeratingChargingCurrent / 10));
+    printf("%02X      %02X",ShmPsuGrouping->OutputRelayConfig[gun].CtrlValue, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
+    printf("\r\n");
 
-    for(int i = 0; i < 4; i++)
+    return 1;
+}
+
+void ShowGroupingInfo(void)
+{
+    int target = 0;
+
+    printf("\r\n");
+    printf(" Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay\r\n");
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
     {
         target = ShmPsuGrouping->Layout[i];
-        printf("\r\n  %d   (%2d)   %2d  %d     %02X    ",
-            target + 1, _chargingData[target]->SystemStatus, ShmChargerInfo->PsuGrouping.GroupCollection[target].Role,
-            ShmChargerInfo->PsuGrouping.GroupCollection[target].Partner.Quantity, ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup);
+        ShowSingleGroupingInfo(target);
+    }
+    printf("\r\n");
+}
 
-        for(int j = 0; j < 3; j++)
+// Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay
+//  1   (00)   00  3     00    [00] [00] [00]    0000 V     0000 A    0000 kW    0000 A   0000 A   00      XX
+void ShowGroupingCmd(char *inputCmd, unsigned int opt)
+{
+    bool keepRun = false;
+    bool reflash = false;
+    int time = 0, target = 0;
+    struct timespec _Loop_time;
+
+    if((opt & OPTION_REFLASH) || (opt & OPTION_LOOP) > 0)
+    {
+        keepRun = true;
+    }
+    printf("\r\n");
+    printf(" Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay\r\n");
+    do
+    {
+        time = GetTimeoutValue(_Loop_time) / mSEC_VAL;
+        if(time >= 1000)
         {
-            if(ShmChargerInfo->PsuGrouping.GroupCollection[target].Role == 1 && j < ShmChargerInfo->PsuGrouping.GroupCollection[target].Partner.Quantity)
+            if(reflash)
             {
-                printf("[%02X] ", ShmChargerInfo->PsuGrouping.GroupCollection[target].Partner.Member[j]);
+                ConsoleReflash(CONNECTOR_QUANTITY, 1);
             }
-            else
+
+            for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+            {
+                target = ShmPsuGrouping->Layout[i];
+                ShowSingleGroupingInfo(target);
+            }
+
+            GetClockTime(&_Loop_time);
+
+            if((opt & OPTION_REFLASH) > 0)
             {
-                printf("     ");
+                reflash = true;
             }
         }
-        printf("   %4d V     %4d A    %4d kW    %4d A   %4d A   ",
-            (int)_chargingData[target]->PresentChargingVoltage, (int)_chargingData[target]->PresentChargingCurrent,
-            (int)(_chargingData[target]->AvailableChargingPower / 10), (int)(_chargingData[target]->AvailableChargingCurrent / 10),
-            (int)(_chargingData[target]->DeratingChargingCurrent / 10));
-        printf("%02X      %02X",ShmPsuGrouping->OutputRelayConfig[target].CtrlValue, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
-    }
-    printf("\r\n\r\nSystem Capability Current = %4d.%01d A, Power = %3d.%01d kW",
-        (ShmPsuData->SystemAvailableCurrent / 10), (ShmPsuData->SystemAvailableCurrent % 10),
-        (ShmPsuData->SystemAvailablePower / 10), (ShmPsuData->SystemAvailablePower % 10));
 
-    printf("\r\n\r\n");
+        if(keepRun)
+        {
+            keepRun = IsLoopStopCmd() ? false : true;
+            usleep(10000);
+        }
+    }while(keepRun);
+    printf("\r\n");
 }
 
 void PsuGroupSwitchToIdle(byte group)
@@ -1954,8 +2063,8 @@ void SetTestControl(char *v1, char *v2)
 //  1    00     00      0   0000 V   000.0 A    0000 A    XXX.XX   XXX.XX    XXX kw     XXX kW    XXX kW      XX      0xXXXX  0xXXXX  0xXXXX  0xXXXX   0xXXXX  0xXXXX
 
 //                                                        Group     Gun                                       DiffP   Available               Psu Group Control
-// Gun  Role  Master  K1K2   GTVol     GTCur  StableCur  Loading  Loading  DiffP_Ava  DiffP_Cap  DiffP_Lim  ConfigLim  Partner  IdleCtrl Master   Stop  Derating  Extend   Slave
-//  1    00     00      0   0000 V   000.0 A    0000 A    XXX.XX   XXX.XX    XXX kw     XXX kW    XXX kW      XXX kW     XX      0xXXXX  0xXXXX  0xXXXX  0xXXXX   0xXXXX  0xXXXX
+// Gun  Role  Master  K1K2   GTVol     GTCur  StableCur  Loading  Loading  DiffP_Ava  DiffP_Cap  DiffP_Lim  ConfigLim  Partner  IdleCtrl Master   Stop  Derating  Extend   Slave   Dummy
+//  1    00     00      0   0000 V   000.0 A    0000 A    XXX.XX   XXX.XX    XXX kw     XXX kW    XXX kW      XXX kW     XX      0xXXXX  0xXXXX  0xXXXX  0xXXXX   0xXXXX  0xXXXX  0xXXXX
 void ShowGroupingDemand(char *inputCmd, unsigned int opt)
 {
     bool keepRun = false;
@@ -2014,7 +2123,7 @@ void ShowGroupingDemand(char *inputCmd, unsigned int opt)
     sprintf(lineString, " Gun  Role  Master  K1K2   GTVol     GTCur  StableCur  Loading  Loading  DiffP_Ava  DiffP_Cap  DiffP_Lim  ConfigLim");
     if(fullInfo)
     {
-        sprintf(tempString, "  Partner  IdleCtrl Master   Stop  Derating  Extend   Slave");
+        sprintf(tempString, "  Partner  IdleCtrl Master   Stop  Derating  Extend   Slave   Dummy");
         strcat(lineString, tempString);
     }
     if(!outputFile)
@@ -2075,14 +2184,15 @@ void ShowGroupingDemand(char *inputCmd, unsigned int opt)
                     if(fullInfo)
                     {
                         int partner_quantity = GetPsuGroupAvailable(target);
-                        sprintf(tempString, "     %2d      0x%04X  0x%04X  0x%04X  0x%04X   0x%04X  0x%04X",
+                        sprintf(tempString, "     %2d      0x%04X  0x%04X  0x%04X  0x%04X   0x%04X  0x%04X  0x%04X",
                             partner_quantity,
                             ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.IdleCtrlValue,
                             ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.MasterCtrlValue,
                             ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.StopChargingCtrlValue,
                             ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.DeratingCtrlValue,
                             ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue,
-                            ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.SlaveCtrlValue);
+                            ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.SlaveCtrlValue,
+                            ShmPsuGrouping->GroupCollection[target].GroupCtrl.RoleCtrl.DummyMasterCtrlValue);
                         strcat(lineString, tempString);
                     }
                 //}
@@ -2138,7 +2248,7 @@ void SetGunStartCharging(char *inputCmd, unsigned int opt, unsigned char isWeb)
 
     if(totalCnt != maxPara)
     {
-        printf("Input cmd fail ------  gunchg [gun 1-4] [voltage 0-1000] [current 0-100]\r\n\r\n");
+        printf("Input cmd fail ------  gunchg [gun 1-4] [voltage 0-1000] [current 0-1000]\r\n\r\n");
         return;
     }
 
@@ -2731,13 +2841,12 @@ void ShowStatus(void)
 
 void ShowWhiteCardList(void)
 {
-    printf("\r\nWhite Card List");
+    printf("\r\n");
+    printf("White Card List\r\n");
     for(int i = 0; i < 10; i++)
     {
-        printf("\r\n White Card [%2d]: %s", i + 1, (char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i]);
+        printf(" *White Card [%2d]: %s\r\n", i + 1, (char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i]);
     }
-
-    printf("\r\n\r\n");
 }
 
 void WriteWhiteCard(char *v1, char *v2)
@@ -3048,6 +3157,7 @@ void ShowWebChargingInfo(void)
     printf(" *Max Charging Duration: %4d Minutes\r\n", ShmSysConfigAndInfo->SysConfig.MaxChargingDuration);
     printf(" *Max Charging Soc     : %4d %%\r\n", ShmSysConfigAndInfo->SysConfig.MaxChargingSoc);
     printf(" *StopCharging By Button[%7s]\r\n", ShmSysConfigAndInfo->SysConfig.StopChargingByButton > 0 ? "Enable" : "Disable");
+    printf(" *Fan Control Policy   : %s\r\n", ShmSysConfigAndInfo->SysConfig.FanControlPolicy == _FAN_POLICY_AUTO_MODE ? STR_FAN_AUTO_MODE : STR_FAN_QUITE_MODE);
     printf(" *Billing[%7s]\r\n", ShmSysConfigAndInfo->SysConfig.BillingData.isBilling > 0 ? "Enable" : "Disable");
     printf("  - Currency[%2d]\r\n", ShmSysConfigAndInfo->SysConfig.BillingData.Currency);
 }
@@ -3264,6 +3374,20 @@ void ShowWebAllInfo(void)
     ShowWebBackendInfo();
 }
 
+void ShowFanSpeed(void)
+{
+    printf("\r\n");
+    printf("Fan Speed\r\n");
+    printf(" *TestFanSpeed   : %5d\r\n", ShmFanModuleData->TestFanSpeed);
+    printf(" *FanSpeed [Auto]: %5d\r\n", ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed);
+    printf(" *FanSpeed Target: %5d\r\n", ShmFanModuleData->SetFan1Speed);
+    printf(" *Present Speed\r\n");
+    printf("  -Fan 1 Speed   : %5d \n", ShmFanModuleData->PresentFan1Speed);
+    printf("  -Fan 2 Speed   : %5d \n", ShmFanModuleData->PresentFan2Speed);
+    printf("  -Fan 3 Speed   : %5d \n", ShmFanModuleData->PresentFan3Speed);
+    printf("  -Fan 4 Speed   : %5d \n", ShmFanModuleData->PresentFan4Speed);
+}
+
 void ShowWebInfo(char *inputCmd, unsigned int opt)
 {
     int totalCnt = 0, maxPara = 0;
@@ -3279,11 +3403,12 @@ void ShowWebInfo(char *inputCmd, unsigned int opt)
 
     bool find = false;
     int showItem = 0;
-    int itemLen = 8;
-    char strItem[32][32] = {"system", "charging", "network", "backend", "all", "eth", "wifi", "4g"};
+    int itemLen = 10;
+    char strItem[32][32] = {"system", "charging", "network", "backend", "all", "eth", "wifi", "4g", "white", "speed"};
     void *actionList[32] = {
         &ShowWebSystemInfo, &ShowWebChargingInfo, &ShowWebNetworkInfo, &ShowWebBackendInfo,
-        &ShowWebAllInfo, &ShowWebEthernetOnly, &ShowWebWiFiOnly, &ShowWeb3G4GOnly};
+        &ShowWebAllInfo, &ShowWebEthernetOnly, &ShowWebWiFiOnly, &ShowWeb3G4GOnly,
+        &ShowWhiteCardList, &ShowFanSpeed};
     void (*ItemAction)();
 
     for(showItem = 0; showItem < itemLen; showItem++)
@@ -3810,7 +3935,7 @@ void EvCommMsgDebug(char *inputCmd, unsigned int opt)
     bool find = false;
     int reg = 0, enable = 0;
 
-    if(strcmp(&MultiSubCmd[0][0], "0x") == EQUAL && strlen(&MultiSubCmd[0][0]) > 2)
+    if(strncmp(&MultiSubCmd[0][0], "0x", 2) == EQUAL && strlen(&MultiSubCmd[0][0]) > 2)
     {
         reg = (int)strtol(&MultiSubCmd[0][0], NULL, 16);
     }
@@ -3818,7 +3943,19 @@ void EvCommMsgDebug(char *inputCmd, unsigned int opt)
     {
         reg = atoi(&MultiSubCmd[0][0]);
     }
-    enable = atoi(&MultiSubCmd[1][0]);
+
+    if(strcmp(&MultiSubCmd[1][0], "enable") == EQUAL)
+    {
+        enable = 1;
+    }
+    else if(strcmp(&MultiSubCmd[1][0], "disable") == EQUAL)
+    {
+        enable = 0;
+    }
+    else
+    {
+        enable = atoi(&MultiSubCmd[1][0]);
+    }
 
     if(enable > 1 || enable < 0)
     {
@@ -3903,7 +4040,18 @@ void EvCommIdDebug(char *inputCmd, unsigned int opt)
 
     int id = 0, enable = 0;
     id = atoi(&MultiSubCmd[0][0]);
-    enable = atoi(&MultiSubCmd[1][0]);
+    if(strcmp(&MultiSubCmd[1][0], "enable") == EQUAL)
+    {
+        enable = 1;
+    }
+    else if(strcmp(&MultiSubCmd[1][0], "disable") == EQUAL)
+    {
+        enable = 0;
+    }
+    else
+    {
+        enable = atoi(&MultiSubCmd[1][0]);
+    }
 
     if(enable > 1 || enable < 0)
     {
@@ -4346,6 +4494,31 @@ bool CleanMaintainServerURL(void)
     return true;
 }
 
+bool SetFanControlPolicy(char *policy)
+{
+    int _FanMode = _FAN_POLICY_AUTO_MODE;
+    char *strFanMode[] = {STR_FAN_AUTO_MODE, STR_FAN_QUITE_MODE};
+
+    if(strcmp(policy, "auto") == EQUAL)
+    {
+        _FanMode = _FAN_POLICY_AUTO_MODE;
+    }
+    else if(strcmp(policy, "quite") == EQUAL)
+    {
+        _FanMode = _FAN_POLICY_QUITE_MODE;
+    }
+    else
+    {
+        printf("Fan Policy: [%s] is Illegal\r\n", policy);
+        printf(" [value] auto | quite\r\n");
+        return false;
+    }
+
+    ShmSysConfigAndInfo->SysConfig.FanControlPolicy = _FanMode;
+    printf("Set Fan Policy: [%s] OK\r\n", strFanMode[ShmSysConfigAndInfo->SysConfig.FanControlPolicy]);
+    return true;
+}
+
 void FlashSetCmd(char *inputCmd, unsigned int opt)
 {
     char subMain[MAX_SUB_CMD_LENGTH];
@@ -4357,17 +4530,18 @@ void FlashSetCmd(char *inputCmd, unsigned int opt)
     bool find = false;
     int actIndex = 0;
 
-    int maxLen = 20;
+    int maxLen = 21;
     char strWriteItem[32][32] = {
         "model", "sn", "sysid", "auth", "evccid", "qrmode", "qrcode", "led",
         "energy", "power", "current", "time", "soc", "stopbtn", "policy", "backend",
-        "boxid", "vendor", "receipt", "maintain"};
+        "boxid", "vendor", "receipt", "maintain", "fan"};
     bool (*writeFlashList[32])(char *) = {
         &SetModelName, &SetSerialNumber, &SetSystemID, &SetAuthorisationMode,
         &SetAuthrizeByEVCCID, &SetQRCodeMadeMode, &SetQRCodeContent, &SetLEDIntensity,
         &SetMaxChargingEnergy, &SetMaxChargingPower, &SetMaxChargingCurrent, &SetMaxChargingDuration,
         &SetMaxChargingSoc, &SetStopChargingByButton, &SetOfflinePolicy, &SetOcppServerURL,
-        &SetChargeBoxId, &SetChargePointVendor, &SetOcppReceiptrURL, &SetMaintainServerURL};
+        &SetChargeBoxId, &SetChargePointVendor, &SetOcppReceiptrURL, &SetMaintainServerURL,
+        &SetFanControlPolicy};
 
     bool (*WriteFlashAct)(char *);
 
@@ -5530,6 +5704,32 @@ void DiagnosticsCmd(char *inputCmd)
     printf("Input cmd fail ------  super [diagnostics] [enable]\r\n\r\n");
 }
 
+void Rs485DebugEnable(bool enable)
+{
+    ShmChargerInfo->Control.DebugCtrl.bits.MsgInternalComm = enable ? true : false;
+    printf("\r\n");
+    printf("Rs485 internal comm debug %s\r\n\r\n", enable ? "enable" : "disable");
+}
+
+void Rs485DebugCmd(char *inputCmd)
+{
+    char subMain[MAX_SUB_CMD_LENGTH];
+    char subSub[MAX_SUB_CMD_LENGTH];
+
+    memset(subMain, 0x00, sizeof(subMain));
+    memset(subSub, 0x00, sizeof(subSub));
+
+    if(MainAndSubCommandParsing(inputCmd, subMain, subSub) == 1)
+    {
+        bool enable = strcmp(subMain, "enable") == 0 ? true : false;
+
+        Rs485DebugEnable(enable);
+        return;
+    }
+    printf("\r\n");
+    printf("Input cmd fail ------  super [rs485debug] [enable | disable]\r\n\r\n");
+}
+
 void SuperMode(char *inputCmd, unsigned int opt)
 {
     char subMain[MAX_SUB_CMD_LENGTH];
@@ -5563,9 +5763,15 @@ void SuperMode(char *inputCmd, unsigned int opt)
             DiagnosticsCmd(subSub);
             return;
         }
+
+        if(strcmp(subMain, "rs485debug") == 0)
+        {
+            Rs485DebugCmd(subSub);
+            return;
+        }
     }
     printf("\r\n");
-    printf("Input cmd fail ------  super [customized | tilt | standby | diagnostics] [...]\r\n\r\n");
+    printf("Input cmd fail ------  super [customized | tilt | standby | diagnostics | rs485debug] [...]\r\n\r\n");
 }
 
 int ShowPsuCount(void)
@@ -5652,8 +5858,8 @@ int ShowPsuOutput(void)
 
 int ShowPsuGroupInfo(int group)
 {
-    if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
-    {
+    //if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
+    //{
         printf("  G-%d    %2d  %4d.%d V  %4d.%d A  %4d kW",
             group + 1,
             ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity,
@@ -5678,11 +5884,11 @@ int ShowPsuGroupInfo(int group)
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].bits.Alarm,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].bits.Fault,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].bits.Output);
-    }
-    else
-    {
-        printf("  G-%d    %2d     N/A        N/A      N/A      N/A      N/A\r\n", group + 1, ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity);
-    }
+    //}
+    //else
+    //{
+    //    printf("  G-%d    %2d     N/A        N/A      N/A      N/A      N/A\r\n", group + 1, ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity);
+    //}
     return 1;
 }
 
@@ -5919,6 +6125,46 @@ void PsuCmd(char *inputCmd, unsigned int opt)
     printf("\r\n");
 }
 
+void FanSpeedCmd(char *inputCmd, unsigned int opt)
+{
+    bool keepRun = false;
+    bool reflash = false;
+    int time = 0;
+    struct timespec _Loop_time;
+
+    if((opt & OPTION_REFLASH) || (opt & OPTION_LOOP) > 0)
+    {
+        keepRun = true;
+    }
+
+    do
+    {
+        time = GetTimeoutValue(_Loop_time) / mSEC_VAL;
+        if(time >= 1000)
+        {
+            if(reflash)
+            {
+                ConsoleReflash(1, 10);
+            }
+
+            ShowFanSpeed();
+            GetClockTime(&_Loop_time);
+
+            if((opt & OPTION_REFLASH) > 0)
+            {
+                reflash = true;
+            }
+        }
+
+        if(keepRun)
+        {
+            keepRun = IsLoopStopCmd() ? false : true;
+            usleep(10000);
+        }
+    }while(keepRun);
+    printf("\r\n");
+}
+
 int main(int argc, char *argv[])
 {
     char newString[32][MAX_SUB_CMD_LENGTH];
@@ -6061,13 +6307,9 @@ int main(int argc, char *argv[])
 		    // CSU 自我檢測狀態
 			RunSelfProc(newString[1]);
 		}
-		else if(strcmp(newString[0], "ver") == 0)
+		else if(strcmp(mainCmd, "ver") == 0)
 		{
-			//if (strcmp(newString[1], "-1") == 0	|| strcmp(newString[1], "") == 0)
-			//	continue;
-			// 取 FW 版號
-			//GetFwVerProc(newString[1]);
-			ShowFwVer();
+			ShowFwVer(subCmd, option);
 		}
         else if(strcmp(mainCmd, "update") == 0)
 		{
@@ -6106,10 +6348,9 @@ int main(int argc, char *argv[])
 		    // 設定風扇速度
 			SetFanSpeed(newString[1]);
 		}
-		else if(strcmp(newString[0], "speed") == 0)
+		else if(strcmp(mainCmd, "speed") == 0)
 		{
-		    // 取得風扇速度
-			GetFanSpeed();
+		    FanSpeedCmd(subCmd, option);
 		}
 		else if(strcmp(newString[0], "debug") == 0)
 		{
@@ -6201,11 +6442,7 @@ int main(int argc, char *argv[])
         }
         else if(strcmp(newString[0], "group") == 0)
         {
-            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
-            {
-                ShowGroupingInfo();
-                continue;
-            }
+            ShowGroupingCmd(subCmd, option);
         }
         else if(strcmp(mainCmd, "gdmd") == 0)
         {
@@ -6254,6 +6491,7 @@ int main(int argc, char *argv[])
         else if(strcmp(newString[0], "whiteR") == 0)
         {
             ShowWhiteCardList();
+            printf("\r\n");
         }
         else if(strcmp(newString[0], "whiteW") == 0)
         {

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 317 - 429
EVSE/Projects/DO360/Apps/internalComm.c


+ 17 - 29
EVSE/Projects/DO360/Apps/internalComm.h

@@ -361,39 +361,27 @@ typedef struct AC_Charging_Current
 }
 Ac_Charging_current;
 
-extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
-extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
-extern unsigned char Query_Present_InputVoltage(unsigned char fd, unsigned char targetAddr, PresentInputVoltage *Ret_Buf);
-extern unsigned char Query_DC_InputVoltage(unsigned char fd, unsigned char targetAddr, DCInputVoltage *Ret_Buf);
-extern unsigned char Query_Present_OutputVoltage(unsigned char fd, unsigned char targetAddr, PresentOutputVoltage *Ret_Buf);
-extern unsigned char Query_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSpeed *Ret_Buf);
-extern unsigned char Query_Temperature(unsigned char fd, unsigned char targetAddr, Temperature *Ret_Buf);
-extern unsigned char Query_Aux_PowerVoltage(unsigned char fd, unsigned char targetAddr, AuxPower *Ret_Buf);
-extern unsigned char Query_Relay_Output(unsigned char fd, unsigned char targetAddr, Relay *Ret_Buf);
-extern unsigned char Query_Gfd_Adc(unsigned char fd, unsigned char targetAddr, Gfd *Ret_Buf);
-extern unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf);
-extern unsigned char Query_Model_Name(unsigned char fd, unsigned char targetAddr, unsigned char *modelname);
-
-extern unsigned char Config_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSpeed *Set_Buf);
-extern unsigned char Config_Relay_Output(unsigned char fd, unsigned char targetAddr, Relay *Set_Buf);
-extern unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf);
-extern unsigned char Config_Gfd_Value(unsigned char fd, unsigned char targetAddr, Gfd_config *Set_Buf);
-extern unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsigned char *modelname);
-extern unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf);
+extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf, int debug);
+extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf, int debug);
+extern unsigned char Query_Present_InputVoltage(unsigned char fd, unsigned char targetAddr, PresentInputVoltage *Ret_Buf, int debug);
+extern unsigned char Query_DC_InputVoltage(unsigned char fd, unsigned char targetAddr, DCInputVoltage *Ret_Buf, int debug);
+extern unsigned char Query_Present_OutputVoltage(unsigned char fd, unsigned char targetAddr, PresentOutputVoltage *Ret_Buf, int debug);
+extern unsigned char Query_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSpeed *Ret_Buf, int debug);
+extern unsigned char Query_Relay_Output(unsigned char fd, unsigned char targetAddr, Relay *Ret_Buf, int debug);
+extern unsigned char Query_Gfd_Adc(unsigned char fd, unsigned char targetAddr, Gfd *Ret_Buf, int debug);
+
+extern unsigned char Config_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSpeed *Set_Buf, int debug);
+extern unsigned char Config_Relay_Output(unsigned char fd, unsigned char targetAddr, Relay *Set_Buf, int debug);
+extern unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf, int debug);
+extern unsigned char Config_Gfd_Value(unsigned char fd, unsigned char targetAddr, Gfd_config *Set_Buf, int debug);
+extern unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsigned char *modelname, int len, int debug);
+extern unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf, int debug);
 
 extern unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned int crc32);
 extern unsigned char Update_Abord(unsigned char fd, unsigned char targetAddr);
 extern unsigned char Update_Transfer(unsigned char fd, unsigned char targetAddr, unsigned int startAddr, unsigned char *data, unsigned short int length);
 extern unsigned char Update_Finish(unsigned char fd, unsigned char targetAddr);
 
-extern unsigned char Query_AC_Status(unsigned char fd, unsigned char targetAddr, Ac_Status *Ret_Buf);
-extern unsigned char Query_AC_Alarm_Code(unsigned char fd, unsigned char targetAddr, Ac_Alarm_code *Ret_Buf);
-extern unsigned char Query_Charging_Energy(unsigned char fd, unsigned char targetAddr, Ac_Charging_energy *Ret_Buf);
-extern unsigned char Query_Charging_Current(unsigned char fd, unsigned char targetAddr, Ac_Charging_current *Ret_Buf);
-extern unsigned char Config_LED_Status(unsigned char fd, unsigned char targetAddr, Ac_Led_Status *Ret_Buf);
-extern unsigned char Config_Legacy_Req(unsigned char fd, unsigned char targetAddr, unsigned char _switch);
-extern unsigned char Config_Ac_Duty(unsigned char fd, unsigned char targetAddr, unsigned char _value);
-extern unsigned char Config_CSU_Mode(unsigned char fd, unsigned char targetAddr);
-extern unsigned char Config_Reset_MCU(unsigned char fd, unsigned char targetAddr);
-extern unsigned char Config_Led_Color(unsigned char fd, unsigned char targetAddr, Led_Color *Ret_Buf);
+extern unsigned char Config_LED_Status(unsigned char fd, unsigned char targetAddr, Ac_Led_Status *Ret_Buf, int debug);
+extern unsigned char Config_Led_Color(unsigned char fd, unsigned char targetAddr, Led_Color *Ret_Buf, int debug);
 #endif /* INTERNALCOMM_H_ */

+ 1 - 0
EVSE/Projects/DO360/Apps/kill.sh

@@ -13,6 +13,7 @@ pkill Module_ChargerSelfTest
 pkill Module_CabinetParallel
 pkill Module_LedIndication
 pkill Module_Authorize
+pkill Module_Firewall
 pkill main
 fuser -k /dev/watchdog
 sleep 1

BIN
EVSE/Projects/DO360/Apps/libInfyGroup_PsuCommObj.a


BIN
EVSE/Projects/DO360/Apps/libPhGroup_PsuCommObj.a


+ 203 - 126
EVSE/Projects/DO360/Apps/main.c

@@ -458,7 +458,7 @@ bool _NeedDiagnostics = false;
 //char* rfidPortName = "/dev/ttyS2";
 #if ENABLE_PCBA_TEST == 0
 char* fwVersion = "V2.05.00.0000.00";
-char* subVersion = "03";
+char* subVersion = "04";
 #else
 char* fwVersion = "PCBA.00.04";
 char* subVersion = "00";
@@ -2104,72 +2104,8 @@ void GetFirmwareVersion()
 	sprintf(ShmChargerInfo->SysMisc.MainVersion, fwVersion);
 	sprintf(ShmChargerInfo->SysMisc.SubVersion, subVersion);
 #if ENABLE_PCBA_TEST == 0
-	byte count = 0, chademo = 0, ccs = 0, gb = 0;
-	for(uint8_t idx=0;idx<3;idx++)
-	{
-		if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'J')
-		{
-			chademo++;
-			count++;
-		}
-		else  if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'G')
-		{
-			gb++;
-			count++;
-		}
-		else  if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'U' ||
-				ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'E')
-		{
-			ccs++;
-			count++;
-		}
-	}
 
-	if (count == 1)
-	{
-		if (chademo > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '1';
-		else if (ccs > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '2';
-		else if (gb > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '3';
-	}
-	else
-	{
-		if (chademo > 0 && ccs > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '4';
-		else if (chademo > 0 && gb > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '5';
-		else if (ccs > 0 && gb > 0)
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '6';
-	}
-
-	// Get network option from model name
-	switch(ShmSysConfigAndInfo->SysConfig.ModelName[10])
-	{
-		case 'B':
-		case 'U':
-			//Blue tooth
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '3';
-			break;
-		case 'W':
-			// WIFI
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '1';
-			break;
-		case 'T':
-			// 3G/4G
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '2';
-			break;
-        case 'D':
-            ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '5';
-            break;
-		default:
-			// LAN
-			ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '0';
-			break;
-	}
-	// Get rating power from model name
-	memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[4], 0x03);
+	GetFullFirmwareVersion(fwVersion, (char *)ShmSysConfigAndInfo->SysConfig.ModelName, (char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
 
 	// Get IEC or UL
 	char _buf[3] = {0};
@@ -2459,7 +2395,7 @@ void InitialPowerCabinetSetting(void)
 
 void Initial6ParallelSetting(void)
 {
-    if(ShmSysConfigAndInfo->SysConfig.ModelName[11] == '3')
+    if(ShmSysConfigAndInfo->SysConfig.ModelName[11] >= '3' && ShmSysConfigAndInfo->SysConfig.ModelName[11] <= '9')
     {
         ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay = 1;
     }
@@ -2588,6 +2524,7 @@ void SpawnNormalService(void)
 	system("/root/Module_CabinetParallel &");
 	system("/root/Module_LedIndication &");
     system("/root/Module_Authorize &");
+    system("/root/Module_Firewall &");
 }
 
 void SpawnOcppService(void)
@@ -3218,6 +3155,17 @@ void CheckErrorOccurStatus(byte index)
     {
         if(strncmp((char *)chargingInfo[index]->ConnectorAlarmCode, "", 6) == EQUAL)
         {
+            char *strGunError[] = {"042279", "041039", "041040", "042358", "042359"};
+
+            for(int i = 0; i < MAX_GUN_ERROR_QUANTITY; i++)
+            {
+                if((ShmChargerInfo->GunError[index].ErrFlag.ErrorValue & (1 << i)) > 0)
+                {
+                    memcpy(ShmChargerInfo->GunError[index].GunAlarmCode, strGunError[i], 6);
+                    break;
+                }
+            }
+
             memcpy(chargingInfo[index]->ConnectorAlarmCode, ShmChargerInfo->GunError[index].GunAlarmCode, 6);
         }
         if(!chargingInfo[index]->ChargingStopFlag.bits.AlarmStop)
@@ -6075,6 +6023,7 @@ void KillTaskExceptPrimary()
     system("killall Module_LedIndication");
     system("killall Module_EvComm");
     system("killall Module_InternalComm");
+    system("killall Module_Firewall");
     KillPowerModuleTask();
     system("killall Module_4g &");
     system("killall Module_Wifi &");
@@ -6096,6 +6045,7 @@ void KillAllTask()
 	system("killall Module_EvComm");
 	system("killall Module_LcmControl");
 	system("killall Module_InternalComm");
+	system("killall Module_Firewall");
 	KillPowerModuleTask();
 	Kill_Ocpp_Service();
 	Kill_MaintainOcpp_Service();
@@ -7063,7 +7013,7 @@ void TriggerDispenserHardwareReboot(void)
         if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].ConnectorQuantity > 0)
         {
             if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootConfirm == 0 &&
-                !Is_Dispenser_MiscCommand(i, MISC_DISP_SOFTWARE_RESET))
+                !Is_Dispenser_MiscCommand(i, MISC_DISP_HARDWARE_REBOOT))
             {
                 trigger = TRUE;
                 Set_Dispenser_MiscCommand(i, MISC_DISP_HARDWARE_REBOOT);
@@ -8734,7 +8684,8 @@ void CheckDiagnosticsReq(void)
     char _IpAddress[32];
     char cmdBuf[256] = {0};
 
-    if(Is_Ocpp_GetDiagnosticsReq() || ShmChargerInfo->Control.Diagnostics.DiagnosticsType != DIAGNOSTICS_TYPE_NONE)
+    if(Is_Ocpp_GetDiagnosticsReq() || ShmChargerInfo->Control.Diagnostics.DiagnosticsType != DIAGNOSTICS_TYPE_NONE ||
+        ShmSysConfigAndInfo->SysInfo.isDispenserLog)
     {
         // check dispenser status and set diagnostics request
         for(int i = 0; i < MAX_DISPENSER_QUANTITY; i++)
@@ -8816,6 +8767,10 @@ void CheckDiagnosticsReq(void)
             {
                 ShmChargerInfo->Control.Diagnostics.DiagnosticsType = DIAGNOSTICS_TYPE_NONE;
             }
+            if(ShmSysConfigAndInfo->SysInfo.isDispenserLog)
+            {
+                ShmSysConfigAndInfo->SysInfo.isDispenserLog = false;
+            }
             LOG_INFO("Dispenser Diagnostics Completed!");
         }
     }
@@ -8845,7 +8800,10 @@ void CheckOcppStatus()
 			{
 				if (chargingInfo[_index]->SystemStatus != S_IDLE &&
 						chargingInfo[_index]->SystemStatus != S_RESERVATION &&
-						chargingInfo[_index]->SystemStatus != S_MAINTAIN)
+						chargingInfo[_index]->SystemStatus != S_MAINTAIN &&
+						chargingInfo[_index]->SystemStatus != S_FAULT &&
+						!(chargingInfo[_index]->SystemStatus == S_COMPLETE && ShmSysConfigAndInfo->SysInfo.ConnectorInfo[_index].Parameter.bits.PsuReleasable) &&
+						!(chargingInfo[_index]->SystemStatus == S_ALARM && ShmSysConfigAndInfo->SysInfo.ConnectorInfo[_index].Parameter.bits.PsuReleasable))
 				{
 					canReset = false;
 					//if (chargingInfo[_index]->SystemStatus >= S_REASSIGN && chargingInfo[_index]->SystemStatus < S_TERMINATING)
@@ -8881,7 +8839,7 @@ void CheckOcppStatus()
                     {
                         setChargerMode(i, MODE_MAINTAIN);
                     }
-                    sleep(3);
+                    sleep(5);
                     system("reboot -f");
                 }
 		    }
@@ -8900,7 +8858,7 @@ void CheckOcppStatus()
                     {
                         setChargerMode(i, MODE_MAINTAIN);
                     }
-                    sleep(3);
+                    sleep(5);
                     Kill_Ocpp_Service();
                     KillAllTask();
                     TryCloseWatchdog();
@@ -9374,7 +9332,8 @@ int DB_Open(sqlite3 *db)
                           "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, "
                           "`rebootDatetime` TEXT NOT NULL, "
                           "`model_name` TEXT, "
-                          "`serial_number` TEXT, unique(rebootDatetime) on conflict replace);";
+                          "`serial_number` TEXT"
+                          "`version` TEXT, unique(rebootDatetime) on conflict replace);";
 
     char * createconsumptionSql = "CREATE TABLE IF NOT EXISTS `power_consumption` ( "
                                   "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, "
@@ -9968,9 +9927,11 @@ int DB_Reboot_Record(sqlite3 *db)
     char* errMsg = NULL;
     char insertSql[256];
 
-    sprintf(insertSql, "insert into reboot_record(rebootDatetime, model_name, serial_number) values(CURRENT_TIMESTAMP, '%s', '%s');",
+    sprintf(insertSql, "insert into reboot_record(rebootDatetime, model_name, serial_number, version) values(CURRENT_TIMESTAMP, '%s', '%s', '%s_%s');",
         (char *)ShmSysConfigAndInfo->SysConfig.ModelName,
-        (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber);
+        (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber,
+        fwVersion,
+        subVersion);
 
     if(sqlite3_open(DB_FILE, &db))
     {
@@ -10138,7 +10099,7 @@ int DB_Get_Undisposed_Ocmf(sqlite3 *db, int *gunIndex, char *txId, char *ocmfKey
     return result;
 }
 
-void DB_TryAddRebootRecordColumn(sqlite3 *db)
+void DB_TryAddRebootRecordColumn_Model(sqlite3 *db)
 {
     char **rs;
     int rows, cols;
@@ -10193,6 +10154,50 @@ void DB_TryAddRebootRecordColumn(sqlite3 *db)
     }
 }
 
+void DB_TryAddRebootRecordColumn_Version(sqlite3 *db)
+{
+    char **rs;
+    int rows, cols;
+    char* errMsg = NULL;
+    char sqlString[1024];
+    int result = 0;
+
+    strcpy(sqlString, "select count(*) from pragma_table_info('reboot_record') where name = 'version';");
+
+    if(sqlite3_open(DB_FILE, &db))
+    {
+        LOG_ERROR("Can't open database: %s", sqlite3_errmsg(db));
+        sqlite3_close(db);
+    }
+    else
+    {
+        sqlite3_get_table(db, sqlString, &rs, &rows, &cols, &errMsg);
+        if(rows > 0)
+        {
+            for(int idxRow = 1; idxRow <= rows; idxRow++)
+            {
+                result = atoi(rs[(idxRow * cols) + 0]);
+            }
+        }
+        sqlite3_free_table(rs);
+
+        if(result == 0)
+        {
+            strcpy(sqlString, "ALTER TABLE 'reboot_record' ADD COLUMN 'version' TEXT;");
+            if(sqlite3_exec(db, sqlString, 0, 0, &errMsg) != SQLITE_OK)
+            {
+                result = FAIL;
+                LOG_ERROR("reboot_record add column 'version' error message: %s", errMsg);
+            }
+            else
+            {
+                LOG_INFO("reboot_record ADD COLUMN 'version' successfully");
+            }
+        }
+        sqlite3_close(db);
+    }
+}
+
 void DB_TryAddChargingRecordColumn(sqlite3 *db)
 {
     char **rs;
@@ -10604,20 +10609,25 @@ void CheckTask()
 	if(system("pidof -s Module_ProduceUtils > /dev/null") != 0)
 	{
 	    LOG_ERROR("Module_ProduceUtils not running, restart it.");
-		system ("/root/Module_ProduceUtils &");
+		system("/root/Module_ProduceUtils &");
 	}
 
     if(system("pidof -s Module_EvComm > /dev/null") != 0)
     {
         LOG_ERROR("Module_EvComm not running, restart it.");
-        system ("/root/Module_EvComm &");
+        system("/root/Module_EvComm &");
     }
 
     if(system("pidof -s Module_InternalComm > /dev/null") != 0)
     {
         LOG_ERROR("Module_InternalComm not running, restart it.");
-        system ("/root/Module_InternalComm &");
-        //ShmChargerInfo->Control.SysCtrl.bits.NeedSoftReset = true;
+        system("/root/Module_InternalComm &");
+    }
+
+    if(system("pidof -s Module_Firewall > /dev/null") != 0)
+    {
+        LOG_ERROR("Module_Firewall not running, restart it.");
+        system("/root/Module_Firewall &");
     }
 
     if(!Is_WebServer_Alive())
@@ -11142,10 +11152,22 @@ void CheckConnectorDisconnectionRecovery(unsigned char connector)
     }
 }
 
-bool ConnectorRequestToCharging(unsigned char connector)
+bool IsPsuResourceAvailable(unsigned char connector)
+{
+    bool _available = true;
+
+    if(ShmPsuGrouping->GroupCollection[connector].Role == _GROLE_NO_RESOURCE)
+    {
+        _available = false;
+    }
+
+    return _available;
+}
+
+int ConnectorRequestToCharging(unsigned char connector)
 {
     unsigned char role = 0;
-    bool done = false;
+    int result = WAIT;
 
     role = ShmPsuGrouping->GroupCollection[connector].Role;
 
@@ -11160,7 +11182,7 @@ bool ConnectorRequestToCharging(unsigned char connector)
             break;
 
         case _GROLE_MASTER:
-            done = true;
+            result = PASS;
             break;
 
         case _GROLE_SLAVE:
@@ -11172,14 +11194,26 @@ bool ConnectorRequestToCharging(unsigned char connector)
             break;
 
         case _GROLE_REQUEST_TO_CHARGING:
-            done = true;
+            result = PASS;
+            break;
+
+        case _GROLE_DUMMY_MASTER:
+            if(!ShmPsuGrouping->GroupCollection[connector].GroupCtrl.bits.DummyMasterRequest)
+            {
+                LOG_INFO("Gun %d Wait For Dummy Master", connector + 1);
+            }
+            ShmPsuGrouping->GroupCollection[connector].GroupCtrl.bits.DummyMasterRequest = true;
+            break;
+
+        case _GROLE_DUMMY_FAULT:
+            result = FAIL;
             break;
 
         default:
             break;
     }
 
-    return done;
+    return result;
 }
 
 bool IsConnectorGroupingCompleted(unsigned char connector)
@@ -11286,18 +11320,11 @@ bool IsAvailableBackToIdle(int gun_index)
 
 void CheckGunAvailable(void)
 {
-    if(!ShmChargerInfo->Control.SysCtrl.bits.PsuInit)
+    if(ShmPsuData->Work_Step == _WORK_CHARGING)
     {
-        if(ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK)
+        for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
         {
-            for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
-            {
-                if(ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity > 0)
-                {
-                    ShmChargerInfo->Control.GunAvailable[i] = YES;
-                }
-            }
-            ShmChargerInfo->Control.SysCtrl.bits.PsuInit = true;
+            ShmChargerInfo->Control.GunAvailable[i] = IsPsuResourceAvailable(i) ? YES : NO;
         }
     }
 }
@@ -11424,7 +11451,8 @@ void InitialDataBaseValue(void)
     {
         isDb_ready = true;
 
-        DB_TryAddRebootRecordColumn(localDb);
+        DB_TryAddRebootRecordColumn_Model(localDb);
+        DB_TryAddRebootRecordColumn_Version(localDb);
         DB_TryAddChargingRecordColumn(localDb);
 
         for(int _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
@@ -11667,6 +11695,7 @@ void RestrictChargingCapability(int gunIndex, unsigned short *power, unsigned sh
     int _limitPowerResult = 0;
     int _limitVoltageResult = 0;
     int _limitCurrentResult = 0;
+    int _IndividualLimit = NO;
 
     _limitPowerResult = ShmPsuData->SystemAvailablePower;
     _limitVoltageResult = MAX_OUTPUT_VOLTAGE;
@@ -11747,11 +11776,13 @@ void RestrictChargingCapability(int gunIndex, unsigned short *power, unsigned sh
         if(chargingInfo[gunIndex]->ChargingProfilePower >= 0 && _limitPowerResult > ((int)chargingInfo[gunIndex]->ChargingProfilePower / 100))
         {
             _limitPowerResult = (int)chargingInfo[gunIndex]->ChargingProfilePower / 100;
+            _IndividualLimit = true;
         }
 
         if(chargingInfo[gunIndex]->ChargingProfileCurrent >= 0 && _limitCurrentResult > (int)chargingInfo[gunIndex]->ChargingProfileCurrent)
         {
             _limitCurrentResult = (int)chargingInfo[gunIndex]->ChargingProfileCurrent;
+            _IndividualLimit = true;
         }
     }
 
@@ -11761,6 +11792,7 @@ void RestrictChargingCapability(int gunIndex, unsigned short *power, unsigned sh
         if(chargingInfo[gunIndex]->LocalPowerLimitCurrent >= 0 && _limitCurrentResult > (int)(chargingInfo[gunIndex]->LocalPowerLimitCurrent * 10))
         {
             _limitCurrentResult = (int)(chargingInfo[gunIndex]->LocalPowerLimitCurrent * 10);
+            _IndividualLimit = true;
         }
     }
 
@@ -11771,6 +11803,7 @@ void RestrictChargingCapability(int gunIndex, unsigned short *power, unsigned sh
         if(limitPower != 0 && _limitPowerResult > limitPower)
         {
             _limitPowerResult = limitPower;
+            _IndividualLimit = true;
         }
     }
 
@@ -11779,11 +11812,13 @@ void RestrictChargingCapability(int gunIndex, unsigned short *power, unsigned sh
         _limitCurrentResult > ShmChargerInfo->OutputLimit.GunOtpMaxCurrent[gunIndex])
     {
         _limitCurrentResult = ShmChargerInfo->OutputLimit.GunOtpMaxCurrent[gunIndex];
+        _IndividualLimit = true;
     }
 
     ShmChargerInfo->OutputLimit.GunLimitPower[gunIndex] = _limitPowerResult;
     ShmChargerInfo->OutputLimit.GunLimitVoltage[gunIndex] = _limitVoltageResult;
     ShmChargerInfo->OutputLimit.GunLimitCurrent[gunIndex] = _limitCurrentResult;
+    ShmChargerInfo->OutputLimit.IndividualLimit[gunIndex] = _IndividualLimit;
 
     if(_limitPowerResult != 0 && *power > _limitPowerResult)
     {
@@ -11824,15 +11859,33 @@ void UpdateChargingCapability(void)
 
         RestrictChargingCapability(i, &power, &voltage, &current);
 
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityVoltage = voltage;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityCurrent = current;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityPower = power;
+        if((chargingInfo[i]->SystemStatus >= S_CHARGING && chargingInfo[i]->SystemStatus <= S_ALARM) ||
+            (chargingInfo[i]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[i]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+            (chargingInfo[i]->SystemStatus == S_PREPARING_FOR_EVSE && ShmPsuGrouping->GroupCollection[i].GroupCtrl.bits.CableCheckDone))
+        {
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityVoltage = voltage;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityCurrent = current;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityPower = power;
+        }
+        else
+        {
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityVoltage = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalVoltage > 0 ?
+                (float)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalVoltage : (float)voltage;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityCurrent = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalCurrent > 0 ?
+                (float)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalCurrent : (float)current;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityPower = ShmPsuData->SystemAvailablePower > 0 ?
+                (float)ShmPsuData->SystemAvailablePower : (float)power;
+        }
     }
 }
 
 void GunErrorCollection(void)
 {
     bool _PsuNoResource = false;
+    bool _ParallelRelayWelding = false;
+    bool _ParallelRelayDrivingFault = false;
+    bool _OutputRelayWelding = false;
+    bool _OutputRelayDrivingFault = false;
 
     for(int i = 0; i < MAX_GUN_QUANTITY; i++)
     {
@@ -11847,9 +11900,30 @@ void GunErrorCollection(void)
                 _PsuNoResource = true;
             }
         }
+
+        if(ShmChargerInfo->GunError[i].ErrFlag.bits.ParallelRelayWelding)
+        {
+            _ParallelRelayWelding = true;
+        }
+        if(ShmChargerInfo->GunError[i].ErrFlag.bits.ParallelRelayDrivingFault)
+        {
+            _ParallelRelayDrivingFault = true;
+        }
+        if(ShmChargerInfo->GunError[i].ErrFlag.bits.OutputRelayWelding)
+        {
+            _OutputRelayWelding = true;
+        }
+        if(ShmChargerInfo->GunError[i].ErrFlag.bits.OutputRelayDrivingFault)
+        {
+            _OutputRelayDrivingFault = true;
+        }
     }
 
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = _PsuNoResource;
+    ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayWelding = _ParallelRelayWelding;
+    ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayDriving = _ParallelRelayDrivingFault;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.NormalOutputRelayWelding = _OutputRelayWelding;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.NormalOutputRelayDrivingFault = _OutputRelayDrivingFault;
 }
 
 void UpdateGunPresentChargingPower(int gunIndex)
@@ -12103,11 +12177,7 @@ int main(void)
 		{
 			setChargerMode(gun_index, MODE_IDLE);
 
-            if(ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity > 0 ||
-                !ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK)
-            {
-                ShmChargerInfo->Control.GunAvailable[gun_index] = YES;
-            }
+			CheckGunAvailable();
 		}
 	}
 
@@ -12684,13 +12754,13 @@ int main(void)
                         else if(isEvBoardStopChargeFlag(gun_index) == YES)
                         {
                             LOG_INFO("********** Gun %d Alarm Stop (S_AUTHORIZING) **********", gun_index + 1);
-                            Set_Ocpp_StopReason(gun_index, "Local");
+                            Set_Ocpp_StopReason(gun_index, "EVDisconnected");
                             ChargingAlarmProcess(gun_index);
                         }
                         else if(isNormalStopChargeFlag(gun_index) == YES)
                         {
                             LOG_INFO("********** Gun %d Normal Stop (S_AUTHORIZING) **********", gun_index + 1);
-                            Set_Ocpp_StopReason(gun_index, "EVDisconnected");
+                            Set_Ocpp_StopReason(gun_index, "Local");
                             ChargingTerminalProcess(gun_index);
                         }
                     }
@@ -12721,13 +12791,19 @@ int main(void)
 
                     time = GetTimeoutValue(_SystemStatus_Time[gun_index]) / uSEC_VAL;
 
-                    if(ConnectorRequestToCharging(gun_index))
+                    int isRequestOK = ConnectorRequestToCharging(gun_index);
+
+                    if(isRequestOK == PASS)
                     {
                         setChargerMode(gun_index, MODE_REASSIGN);
                     }
-                    else if(time >= WAIT_REASSIGN_TIME)
+                    else if(time >= WAIT_REASSIGN_TIME || isRequestOK == FAIL)
                     {
-                        if(ShmPsuData->Work_Step != _WORK_CHARGING)
+                        if(isRequestOK == FAIL)
+                        {
+                            LOG_INFO("Gun %d Request To Charging Fail", gun_index + 1);
+                        }
+                        else if(ShmPsuData->Work_Step != _WORK_CHARGING)
                         {
                             LOG_INFO("Gun %d Wait PSU Work Step Timeout", gun_index + 1);
                         }
@@ -12742,7 +12818,7 @@ int main(void)
                             memcpy(chargingInfo[gun_index]->ConnectorAlarmCode, "042279", 6);
                             LOG_INFO("Gun %d No Psu Resource", gun_index + 1);
                         }
-                        Set_Ocpp_StopReason(gun_index, "Local");
+                        Set_Ocpp_StopReason(gun_index, "Other");
                         ChargingAlarmProcess(gun_index);
                         //setChargerMode(gun_index, MODE_IDLE);
                     }
@@ -12793,14 +12869,14 @@ int main(void)
 					{
 						// 板端或後臺要求停止
 					    LOG_INFO("********** Gun %d Alarm Stop (S_PREPARNING) **********", gun_index + 1);
-					    Set_Ocpp_StopReason(gun_index, "Local");
+					    Set_Ocpp_StopReason(gun_index, "EVDisconnected");
 					    ChargingAlarmProcess(gun_index);
 					}
 					else if(isNormalStopChargeFlag(gun_index) == YES)
 					{
                         LOG_INFO("********** Gun %d Normal Stop (S_PREPARNING) %s**********", gun_index + 1,
                             chargingInfo[gun_index]->ChargingStopFlag.bits.ManualStop ? "(ManualStop)" : "");
-                        Set_Ocpp_StopReason(gun_index, "EVDisconnected");
+                        Set_Ocpp_StopReason(gun_index, "Local");
 					    ChargingTerminalProcess(gun_index);
 					}
 					else if(isResetStopChargeFlag(gun_index) == YES)
@@ -12815,7 +12891,7 @@ int main(void)
                     else if(isBackendStopFlag(gun_index))
                     {
                         LOG_INFO("********** Gun %d Backend Stop (S_PREPARNING) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Other");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
 
@@ -12826,10 +12902,10 @@ int main(void)
 
                         if(strncmp((char *)chargingInfo[gun_index]->ConnectorAlarmCode, "", 6) == EQUAL)
                         {
-                            memcpy(chargingInfo[gun_index]->ConnectorAlarmCode, "012279", 6);
+                            memcpy(chargingInfo[gun_index]->ConnectorAlarmCode, "042279", 6);
                             LOG_INFO("Gun %d No Psu Resource", gun_index + 1);
                         }
-					    Set_Ocpp_StopReason(gun_index, "Local");
+					    Set_Ocpp_StopReason(gun_index, "Other");
                         ChargingAlarmProcess(gun_index);
 					}
 				}
@@ -12862,14 +12938,14 @@ int main(void)
 					{
 						// 板端或後臺要求停止
 					    LOG_INFO("********** Gun %d Alarm Stop (S_PREPARING_FOR_EV) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Local");
+					    Set_Ocpp_StopReason(gun_index, "EVDisconnected");
 					    ChargingAlarmProcess(gun_index);
 					}
                     else if(isNormalStopChargeFlag(gun_index) == YES)
                     {
                         LOG_INFO("********** Gun %d Normal Stop (S_PREPARING_FOR_EV) %s**********", gun_index + 1,
                             chargingInfo[gun_index]->ChargingStopFlag.bits.ManualStop ? "(ManualStop)" : "");
-                        Set_Ocpp_StopReason(gun_index, "EVDisconnected");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
                     else if(isResetStopChargeFlag(gun_index) == YES)
@@ -12884,7 +12960,7 @@ int main(void)
                     else if(isBackendStopFlag(gun_index))
                     {
                         LOG_INFO("********** Gun %d Backend Stop (S_PREPARING_FOR_EV) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Other");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
 
@@ -12945,14 +13021,14 @@ int main(void)
 					{
 						// 板端或後臺要求停止
 					    LOG_INFO("********** Gun %d Alarm Stop (S_PREPARING_FOR_EVSE) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Local");
+					    Set_Ocpp_StopReason(gun_index, "EVDisconnected");
 					    ChargingAlarmProcess(gun_index);
 					}
                     else if(isNormalStopChargeFlag(gun_index) == YES)
                     {
                         LOG_INFO("********** Gun %d Normal Stop (S_PREPARING_FOR_EVSE) %s**********", gun_index + 1,
                             chargingInfo[gun_index]->ChargingStopFlag.bits.ManualStop ? "(ManualStop)" : "");
-                        Set_Ocpp_StopReason(gun_index, "EVDisconnected");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
                     else if(isResetStopChargeFlag(gun_index) == YES)
@@ -12973,7 +13049,7 @@ int main(void)
                     else if(isBackendStopFlag(gun_index))
                     {
                         LOG_INFO("********** Gun %d Backend Stop (S_PREPARING_FOR_EVSE) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Other");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
 
@@ -13026,14 +13102,14 @@ int main(void)
 					if (isEvBoardStopChargeFlag(gun_index))
 					{
 					    LOG_INFO("********** Gun %d Alarm Stop (S_CHARGING) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Local");
+					    Set_Ocpp_StopReason(gun_index, "EVDisconnected");
 					    ChargingAlarmProcess(gun_index);
 					}
                     else if(isNormalStopChargeFlag(gun_index) == YES)
                     {
                         LOG_INFO("********** Gun %d Normal Stop (S_CHARGING) %s**********", gun_index + 1,
                             chargingInfo[gun_index]->ChargingStopFlag.bits.ManualStop ? "(ManualStop)" : "");
-                        Set_Ocpp_StopReason(gun_index, "EVDisconnected");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
                     }
                     else if(isResetStopChargeFlag(gun_index) == YES)
@@ -13056,6 +13132,7 @@ int main(void)
                         IsReachConfigMaxChargingSoc(gun_index))
 					{
 					    LOG_INFO("********** Gun %d Backend Condition Stop (S_CHARGING) **********", gun_index + 1);
+					    Set_Ocpp_StopReason(gun_index, "Other");
 						ChargingTerminalProcess(gun_index);
 					}
 					else if(isSessionTargetStopFlag(gun_index) == YES)
@@ -13067,7 +13144,7 @@ int main(void)
 					else if(isBackendStopFlag(gun_index))
 					{
                         LOG_INFO("********** Gun %d Backend Stop (S_CHARGING) **********", gun_index + 1);
-                        Set_Ocpp_StopReason(gun_index, "Other");
+                        Set_Ocpp_StopReason(gun_index, "Local");
                         ChargingTerminalProcess(gun_index);
 					}
 				}
@@ -13077,10 +13154,9 @@ int main(void)
 				{
 					if (isModeChange(gun_index))
 					{
-                        Set_Ocpp_StopReason(gun_index, "Other");
-
                         if (chargingInfo[gun_index]->SystemStatus == S_ALARM)
                         {
+                            Set_Ocpp_StopReason(gun_index, "Other");
                             LOG_INFO("==================       S_ALARM (%x)        ================== \n", gun_index + 1);
                             UpdateErrorCodeToOcpp(gun_index);
 
@@ -13088,6 +13164,7 @@ int main(void)
                         }
                         else
                         {
+                            Set_Ocpp_StopReason(gun_index, "Local");
                             LOG_INFO("==================    S_TERMINATING (%x)     ================== \n", gun_index + 1);
                         }
 

BIN
EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin


BIN
EVSE/Projects/DO360/Images/ramdisk.gz


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно