Browse Source

Merge remote-tracking branch 'origin/DO360'

Folus Wen 2 years ago
parent
commit
61d5e751f7

+ 70 - 10
EVSE/Projects/DO360/Apps/Common.c

@@ -12,6 +12,9 @@
 #include <stdarg.h>
 #include <stdarg.h>
 #include <time.h>
 #include <time.h>
 #include <sys/timeb.h>
 #include <sys/timeb.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include "Common.h"
 #include "Common.h"
 
 
 int StoreSysLogMsg(const char *fmt, ...)
 int StoreSysLogMsg(const char *fmt, ...)
@@ -66,7 +69,7 @@ int StorePsuLogMsg(const char *fmt, ...)
     return rc;
     return rc;
 }
 }
 
 
-int StoreEventLogMsg(const char *fmt, ...)
+int StoreAuthLogMsg(const char *fmt, ...)
 {
 {
     char Buf[4096+256];
     char Buf[4096+256];
     char buffer[4096];
     char buffer[4096];
@@ -83,7 +86,7 @@ int StoreEventLogMsg(const char *fmt, ...)
     SeqEndTime.time = time(NULL);
     SeqEndTime.time = time(NULL);
     tm=localtime(&SeqEndTime.time);
     tm=localtime(&SeqEndTime.time);
 
 
-    sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/EventLog/[%04d.%02d]EventLog",
+    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]AuthLog",
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         buffer,
         buffer,
         tm->tm_year+1900,tm->tm_mon+1);
         tm->tm_year+1900,tm->tm_mon+1);
@@ -92,7 +95,7 @@ int StoreEventLogMsg(const char *fmt, ...)
     return rc;
     return rc;
 }
 }
 
 
-int StoreAuthLogMsg(const char *fmt, ...)
+int StoreEvCommMsg(const char *fmt, ...)
 {
 {
     char Buf[4096+256];
     char Buf[4096+256];
     char buffer[4096];
     char buffer[4096];
@@ -109,7 +112,7 @@ int StoreAuthLogMsg(const char *fmt, ...)
     SeqEndTime.time = time(NULL);
     SeqEndTime.time = time(NULL);
     tm=localtime(&SeqEndTime.time);
     tm=localtime(&SeqEndTime.time);
 
 
-    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]AuthLog",
+    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]EvCommLog",
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         buffer,
         buffer,
         tm->tm_year+1900,tm->tm_mon+1);
         tm->tm_year+1900,tm->tm_mon+1);
@@ -118,7 +121,7 @@ int StoreAuthLogMsg(const char *fmt, ...)
     return rc;
     return rc;
 }
 }
 
 
-int StoreEvCommMsg(const char *fmt, ...)
+int StoreDbMsg(const char *fmt, ...)
 {
 {
     char Buf[4096+256];
     char Buf[4096+256];
     char buffer[4096];
     char buffer[4096];
@@ -135,7 +138,7 @@ int StoreEvCommMsg(const char *fmt, ...)
     SeqEndTime.time = time(NULL);
     SeqEndTime.time = time(NULL);
     tm=localtime(&SeqEndTime.time);
     tm=localtime(&SeqEndTime.time);
 
 
-    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]EvCommLog",
+    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]DbLog",
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         buffer,
         buffer,
         tm->tm_year+1900,tm->tm_mon+1);
         tm->tm_year+1900,tm->tm_mon+1);
@@ -144,7 +147,7 @@ int StoreEvCommMsg(const char *fmt, ...)
     return rc;
     return rc;
 }
 }
 
 
-int StoreDbMsg(const char *fmt, ...)
+int StoreOccupancyMsg(const char *fmt, ...)
 {
 {
     char Buf[4096+256];
     char Buf[4096+256];
     char buffer[4096];
     char buffer[4096];
@@ -161,7 +164,7 @@ int StoreDbMsg(const char *fmt, ...)
     SeqEndTime.time = time(NULL);
     SeqEndTime.time = time(NULL);
     tm=localtime(&SeqEndTime.time);
     tm=localtime(&SeqEndTime.time);
 
 
-    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]DbLog",
+    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]OccupancyLog",
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         buffer,
         buffer,
         tm->tm_year+1900,tm->tm_mon+1);
         tm->tm_year+1900,tm->tm_mon+1);
@@ -170,7 +173,7 @@ int StoreDbMsg(const char *fmt, ...)
     return rc;
     return rc;
 }
 }
 
 
-int StoreOccupancyMsg(const char *fmt, ...)
+int StoreReadCmdLineMsg(const char *fmt, ...)
 {
 {
     char Buf[4096+256];
     char Buf[4096+256];
     char buffer[4096];
     char buffer[4096];
@@ -187,7 +190,7 @@ int StoreOccupancyMsg(const char *fmt, ...)
     SeqEndTime.time = time(NULL);
     SeqEndTime.time = time(NULL);
     tm=localtime(&SeqEndTime.time);
     tm=localtime(&SeqEndTime.time);
 
 
-    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]OccupancyLog",
+    sprintf(Buf,"echo \'%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\' >> /Storage/SystemLog/[%04d.%02d]ReadCmdLineLog",
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
         buffer,
         buffer,
         tm->tm_year+1900,tm->tm_mon+1);
         tm->tm_year+1900,tm->tm_mon+1);
@@ -667,6 +670,63 @@ unsigned short ParsingRatingPower(char *modelname)
     return value;
     return value;
 }
 }
 
 
+unsigned int cal_crc32(unsigned char *data, unsigned int length)
+{
+    unsigned int crc = 0xFFFFFFFF;
+
+    for(size_t i = 0; i < length; i++)
+    {
+        char ch = data[i];
+
+        for(size_t j = 0; j < 8; j++)
+        {
+            unsigned int b = (ch ^ crc) & 1;
+
+            crc >>= 1;
+            if(b)
+            {
+                crc=crc^0xEDB88320;
+            }
+            ch>>=1;
+        }
+    }
+    return ~crc;
+}
+
+unsigned int getFileCrc32(char *filename)
+{
+    unsigned int result = 0;
+
+    int fd = open(filename, O_RDONLY);
+
+    if(fd < 0)
+    {
+        LOG_ERROR("Get File Crc32 Error, Can not open file %s", filename);
+    }
+    else
+    {
+        struct stat st;
+
+        stat(filename, &st);
+        unsigned char *data;
+
+        data = malloc(st.st_size);
+
+        if(read(fd,data,st.st_size) == st.st_size)
+        {
+            result = cal_crc32(data, st.st_size);
+            close(fd);
+        }
+        else
+        {
+            LOG_ERROR("Read file Error %d", st.st_size);
+        }
+
+        free(data);
+    }
+
+    return result;
+}
 
 
 //***************************************** No Use *****************************************
 //***************************************** No Use *****************************************
 float TariffParsing(char *StringItem, char *TariffCode)
 float TariffParsing(char *StringItem, char *TariffCode)

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

@@ -33,22 +33,22 @@
 #define LOG_ERROR(format, args...) StoreSysLogMsg("[%s:%4d][%s][Erro] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define LOG_ERROR(format, args...) StoreSysLogMsg("[%s:%4d][%s][Erro] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define LOG_DBG(format, args...) StoreSysLogMsg("[%s:%4d][%s][Debg] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define LOG_DBG(format, args...) StoreSysLogMsg("[%s:%4d][%s][Debg] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define PSU_LOG(format, args...) StorePsuLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define PSU_LOG(format, args...) StorePsuLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
-#define LOG_EVENT(format, args...) StoreEventLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define AUTH_INFO(format, args...) StoreAuthLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define AUTH_INFO(format, args...) StoreAuthLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define EvMsg_INFO(format, args...) StoreEvCommMsg("[%s:%4d][%s][EvMsg] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define EvMsg_INFO(format, args...) StoreEvCommMsg("[%s:%4d][%s][EvMsg] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define Database_INFO(format, args...) StoreDbMsg("[%s:%4d][%s][DB] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define Database_INFO(format, args...) StoreDbMsg("[%s:%4d][%s][DB] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define Occupancy_INFO(format, args...) StoreOccupancyMsg("[%s:%4d][%s][OF] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
 #define Occupancy_INFO(format, args...) StoreOccupancyMsg("[%s:%4d][%s][OF] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+#define ReadCmd_INFO(format, args...) StoreReadCmdLineMsg(" "format, ##args)
 
 
 #define DB_FILE                     "/Storage/ChargeLog/localCgargingRecord.db"
 #define DB_FILE                     "/Storage/ChargeLog/localCgargingRecord.db"
 #define NETWORK_DB_FILE             "/Storage/EventLog/Eventlog.db"
 #define NETWORK_DB_FILE             "/Storage/EventLog/Eventlog.db"
 
 
 int StoreSysLogMsg(const char *fmt, ...);
 int StoreSysLogMsg(const char *fmt, ...);
 int StorePsuLogMsg(const char *fmt, ...);
 int StorePsuLogMsg(const char *fmt, ...);
-int StoreEventLogMsg(const char *fmt, ...);
 int StoreAuthLogMsg(const char *fmt, ...);
 int StoreAuthLogMsg(const char *fmt, ...);
 int StoreEvCommMsg(const char *fmt, ...);
 int StoreEvCommMsg(const char *fmt, ...);
 int StoreDbMsg(const char *fmt, ...);
 int StoreDbMsg(const char *fmt, ...);
 int StoreOccupancyMsg(const char *fmt, ...);
 int StoreOccupancyMsg(const char *fmt, ...);
+int StoreReadCmdLineMsg(const char *fmt, ...);
 
 
 void GetClockTime(struct timespec *_now_time);
 void GetClockTime(struct timespec *_now_time);
 unsigned long GetTimeoutValue(struct timespec _start_time);
 unsigned long GetTimeoutValue(struct timespec _start_time);
@@ -78,6 +78,7 @@ float GetNowTimePricing(float *price);
 float TccDefaultPriceParsing(char *costString, float *price);
 float TccDefaultPriceParsing(char *costString, float *price);
 
 
 unsigned short ParsingRatingPower(char *modelname);
 unsigned short ParsingRatingPower(char *modelname);
+unsigned int getFileCrc32(char *filename);
 
 
 //***************************************** No Use *****************************************
 //***************************************** No Use *****************************************
 float TariffParsing(char *StringItem, char *TariffCode);
 float TariffParsing(char *StringItem, char *TariffCode);

+ 173 - 17
EVSE/Projects/DO360/Apps/Config.h

@@ -55,6 +55,7 @@ typedef unsigned char               byte;
 #define MAX_MODULE_PER_GROUP        12
 #define MAX_MODULE_PER_GROUP        12
 #define INFY_SINGLE_PSU_POWER       30000           // unit: 1W
 #define INFY_SINGLE_PSU_POWER       30000           // unit: 1W
 #define SM_ChargerInfoKey           3000
 #define SM_ChargerInfoKey           3000
+#define MAX_OUTPUT_VOLTAGE          9500
 
 
 #define SAFETY_TEST_ENABLE          0
 #define SAFETY_TEST_ENABLE          0
 
 
@@ -149,16 +150,6 @@ enum _SYSTEM_STATUS
 	S_NONE,
 	S_NONE,
 };
 };
 
 
-enum _AC_SYSTEM_STATUS
-{
-	AC_SYS_NONE = 	0,
-	AC_SYS_A,
-	AC_SYS_B,
-	AC_SYS_C,
-	AC_SYS_D,
-	AC_SYS_E
-};
-
 #define STR_GUN_TYPE_CHADEMO        "CHAdeMO"
 #define STR_GUN_TYPE_CHADEMO        "CHAdeMO"
 #define STR_GUN_TYPE_CCS            "CCS"
 #define STR_GUN_TYPE_CCS            "CCS"
 #define STR_GUN_TYPE_GBT            "GBT"
 #define STR_GUN_TYPE_GBT            "GBT"
@@ -718,6 +709,62 @@ typedef struct
     int EvCanFd;
     int EvCanFd;
 }FdControl;
 }FdControl;
 
 
+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_TEST_STEP;
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int StandbyTimeDisable:1;          // 0: no effect,                1: disable standby time
+        unsigned int StandbyTimeDisableForTcc:1;    // 0: no effect,                1: disable standby time at specific time for tcc
+        unsigned int StandbyImmediately:1;          // 0: no effect,                1: standby immediately
+        unsigned int CustomizedStandbyTime:1;       // 0: no effect,                1: enable customized standby time
+        unsigned int TiltSensorEnable:1;            // 0: no effect,                1: enable tilt sensor
+        unsigned int res:27;
+    }bits;
+}CustomizedFlagInfo;
+
+typedef struct
+{
+    int TiltSensorStep;
+    int TiltSensorFail;
+    int StandbyTime;                                // unit: 1 minute
+    CustomizedFlagInfo Flag;
+}CustomizedFunctionInfo;
+
+#define DIAGNOSTICS_TYPE_NONE       0
+#define DIAGNOSTICS_TYPE_ALL        1
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int Request:1;                     // 0: no effect,                1: diagnostics request
+        unsigned int Confirm:1;                     // 0: no effect,                1: diagnostics confirm
+        unsigned int Completed:1;                   // 0: no effect,                1: diagnostics completed
+        unsigned int Stop:1;                        // 0: no effect,                1: diagnostics stop
+        unsigned int res:28;
+    }bits;
+}DiagnosticsFlagInfo;
+
+typedef struct
+{
+    int DiagnosticsType;
+    DiagnosticsFlagInfo DispenserDiagnostics[MAX_DISPENSER_QUANTITY];
+}DiagnosticsInfo;
+
 typedef struct
 typedef struct
 {
 {
     unsigned char   MaxDispenser;
     unsigned char   MaxDispenser;
@@ -747,6 +794,9 @@ typedef struct
     unsigned char   GunAvailable[MAX_GROUP_QUANTITY];
     unsigned char   GunAvailable[MAX_GROUP_QUANTITY];
     unsigned char   PsuInitQuantity[MAX_GROUP_QUANTITY];
     unsigned char   PsuInitQuantity[MAX_GROUP_QUANTITY];
     char            ResevedIdTag[MAX_GROUP_QUANTITY][32];
     char            ResevedIdTag[MAX_GROUP_QUANTITY][32];
+
+    CustomizedFunctionInfo  CustomizedInfo;
+    DiagnosticsInfo Diagnostics;
 }SysControl;
 }SysControl;
 // ************************************************************************************************* //
 // ************************************************************************************************* //
 typedef struct
 typedef struct
@@ -788,17 +838,55 @@ typedef union
     unsigned int StatusVal;
     unsigned int StatusVal;
     struct
     struct
     {
     {
-        unsigned int Changed:1;                     // 0: no output,                1: psu is output
-        unsigned int res:31;
+        unsigned int Changed:1;
+        unsigned int Indicated:1;
+        unsigned int res:30;
     }bits;
     }bits;
 }PsuErrorStatusInfo;
 }PsuErrorStatusInfo;
 
 
 typedef struct
 typedef struct
 {
 {
     int ErrorCount;
     int ErrorCount;
-    PsuErrorStatusInfo ErrFlag;
+    PsuErrorStatusInfo PhPwrStateFlag;
     unsigned char PsuError[8];
     unsigned char PsuError[8];
-}PsuErrorCodeInfo;
+}PhPwrStateInfo;
+
+typedef union
+{
+    unsigned char StateVal[4];
+    struct
+    {
+        //StateVal[0]
+        unsigned char OutputShort:1;                // OFF, Red
+        unsigned char State_0_1_7:7;
+        //StateVal[1]
+        unsigned char PsuOff:1;                     // OFF
+        unsigned char PsuFault:1;                   // OFF, Red
+        unsigned char PsuProtect:1;                 // OFF, Yellow
+        unsigned char FanFault:1;                   // OFF, Red Blink
+        unsigned char OverTemperature:1;            // OFF, Yellow
+        unsigned char OutputOverVoltage:1;          // OFF, Red
+        unsigned char WalkInEnable:1;
+        unsigned char CanCommInterrupt:1;           // OFF, Yellow Blink
+        //StateVal[2]
+        unsigned char PowerLimit:1;                 //  ON
+        unsigned char PsuIdRepetition:1;            // OFF, Red
+        unsigned char LoadUnsharing:1;              //  ON, Red
+        unsigned char InputPhaseLost:1;             // OFF, Yellow
+        unsigned char InputUnbalance:1;             //
+        unsigned char InputUnderVoltage:1;          // OFF, Yellow
+        unsigned char InputOverVoltage:1;           // OFF, Yellow
+        unsigned char PfcOff:1;                     // OFF
+        //StateVal[3]
+        unsigned char State_3:8;
+    }bits;
+}InfyPsuStateFlagInfo;
+
+typedef struct
+{
+    PsuErrorStatusInfo InfyPwrStateFlag;
+    InfyPsuStateFlagInfo InfyPwrState;
+}InfyPwrStateInfo;
 
 
 typedef struct
 typedef struct
 {
 {
@@ -808,7 +896,8 @@ typedef struct
     GroupInfoData       GroupLocationInfo[MAX_GROUP_QUANTITY];
     GroupInfoData       GroupLocationInfo[MAX_GROUP_QUANTITY];
     PsuAddressInfoData  PsuAddressInfo[MAX_PSU_MODULE_QUANTITY];
     PsuAddressInfoData  PsuAddressInfo[MAX_PSU_MODULE_QUANTITY];
     PsuStatusInfo       SinglePsuStatus[MAX_PSU_MODULE_QUANTITY];
     PsuStatusInfo       SinglePsuStatus[MAX_PSU_MODULE_QUANTITY];
-    PsuErrorCodeInfo    SinglePsuError[MAX_PSU_MODULE_QUANTITY];
+    PhPwrStateInfo      SinglePhPsuError[MAX_PSU_MODULE_QUANTITY];
+    InfyPwrStateInfo    SingleInfyPwrState[MAX_PSU_MODULE_QUANTITY];
 }PsuPositionInfoData;
 }PsuPositionInfoData;
 // ************************************************************************************************* //
 // ************************************************************************************************* //
 typedef enum
 typedef enum
@@ -947,6 +1036,7 @@ typedef struct
     float                   DiffPower_Capability;               // unit: 1kW, different power between output power and Capability power
     float                   DiffPower_Capability;               // unit: 1kW, different power between output power and Capability power
     float                   DiffPower_Available;                // unit: 1kW, different power between output power and Available power
     float                   DiffPower_Available;                // unit: 1kW, different power between output power and Available power
     float                   DiffPower_PhysicalLimit;            // unit: 1kW, different power between output power and PhysicalLimit power
     float                   DiffPower_PhysicalLimit;            // unit: 1kW, different power between output power and PhysicalLimit power
+    float                   DiffPower_ConfigLimit;              // unit: 1kW, different power between output power and config power
 }PsuGroupCollectionData;
 }PsuGroupCollectionData;
 
 
 typedef struct
 typedef struct
@@ -1388,7 +1478,7 @@ typedef union
         unsigned int OutputRelayDrivingFault:1;         // 0: no effect,    1: DrivingFault
         unsigned int OutputRelayDrivingFault:1;         // 0: no effect,    1: DrivingFault
         unsigned int ParallelRelayWelding:1;            // 0: no effect,    1: Welding
         unsigned int ParallelRelayWelding:1;            // 0: no effect,    1: Welding
         unsigned int ParallelRelayDrivingFault:1;       // 0: no effect,    1: DrivingFault
         unsigned int ParallelRelayDrivingFault:1;       // 0: no effect,    1: DrivingFault
-        unsigned int PsuGroupAllAlarmFault:1;           // 0: no effect,    1: psu group all alarm or fault
+        unsigned int PsuGroupNoResource:1;              // 0: no effect,    1: psu group all alarm or fault >> group no resource
         unsigned int res:27;
         unsigned int res:27;
     }bits;
     }bits;
 }GunErrorFlag;
 }GunErrorFlag;
@@ -1420,6 +1510,11 @@ typedef struct
     int GunManualLimitPower[MAX_GUN_QUANTITY];          // unit: W
     int GunManualLimitPower[MAX_GUN_QUANTITY];          // unit: W
     int GunManualLimitVoltage[MAX_GUN_QUANTITY];        // unit: 0.1V
     int GunManualLimitVoltage[MAX_GUN_QUANTITY];        // unit: 0.1V
     int GunManualLimitCurrent[MAX_GUN_QUANTITY];        // unit: 0.1A
     int GunManualLimitCurrent[MAX_GUN_QUANTITY];        // unit: 0.1A
+
+    // final output limitation
+    int GunLimitPower[MAX_GUN_QUANTITY];                // unit: 0.1kW
+    int GunLimitVoltage[MAX_GUN_QUANTITY];              // unit: 0.1V
+    int GunLimitCurrent[MAX_GUN_QUANTITY];              // unit: 0.1A
 }OutputLimitation;
 }OutputLimitation;
 
 
 typedef enum
 typedef enum
@@ -1496,6 +1591,19 @@ typedef enum
 #define STR_PAID_ONLINE_OK          "PaidOK"
 #define STR_PAID_ONLINE_OK          "PaidOK"
 #define STR_PAID_ONLINE_FAIL        "PaidFail"
 #define STR_PAID_ONLINE_FAIL        "PaidFail"
 
 
+#define STR_NOTIFY_NONE             "Notify None"
+#define STR_GET_OCCUPANCY_FEE       "GetOccupancyFee"
+#define STR_CANCEL_OCCUPANCY_DEDUCT "CancelDeduction"
+#define STR_CANCEL_OCCUPANCY_FEE    "CancelOccupancyFee"
+
+typedef enum
+{
+    _Notify_None                    = 0x00,             // act: None
+    _Notify_GetOccupancyFee         = 0x01,             // act: Get OccupancyFee
+    _Notify_CancelLocalDeduction    = 0x02,             // act: Cancel Local Deduction
+    _Notify_CancelOccupancyFee      = 0x03,             // act: Cancel Occupancy Fee
+}NotifyOccupancyFeeAct;
+
 typedef struct
 typedef struct
 {
 {
     unsigned char MiscStatus;                           // 0: idle, 1: misc request, 2 misc clean, 3: bill update done
     unsigned char MiscStatus;                           // 0: idle, 1: misc request, 2 misc clean, 3: bill update done
@@ -1530,8 +1638,9 @@ typedef union
     {
     {
         unsigned int DeductReq:1;                       // 0: no request,               1: deduct request
         unsigned int DeductReq:1;                       // 0: no request,               1: deduct request
         unsigned int KeepCounting:1;                    // 0: no effect,                1: occupancy keep counting
         unsigned int KeepCounting:1;                    // 0: no effect,                1: occupancy keep counting
+        unsigned int ForceCancel:1;                     // 0: no effect,                1: force cancel occupancy fee because of charging status
         unsigned int SelfReq:1;                         // 0: no request,               1: self request
         unsigned int SelfReq:1;                         // 0: no request,               1: self request
-        unsigned int res:29;
+        unsigned int res:28;
     }bits;
     }bits;
 }OccupancyReqFlag;
 }OccupancyReqFlag;
 
 
@@ -1554,6 +1663,52 @@ typedef struct
     ChargingBillInfoData GunBill[MAX_GUN_QUANTITY];
     ChargingBillInfoData GunBill[MAX_GUN_QUANTITY];
     OccupancyInfoData OccupancyInfo[MAX_GUN_QUANTITY];
     OccupancyInfoData OccupancyInfo[MAX_GUN_QUANTITY];
 }AllBillInfoData;
 }AllBillInfoData;
+
+#define OCMF_SATAUS_INSERTED                            0
+#define OCMF_SATAUS_UPDATED_OK                          1
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int OcmfReceived:1;                    // 0: no request,               1: ocmf info received
+        unsigned int res:31;
+    }bits;
+}GunOcmfFlag;
+
+typedef struct
+{
+    // ocmf file path: /mnt
+    // ocmf file name: Gun_X_TxId_OCMF
+    // X: Gun Id
+    // TxId: Transaction Id
+    char OcmfTxId[36];
+    char PublicKey[200];
+    GunOcmfFlag OcmfFlag;
+}OCMFInfoData;
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int OcmfPending:1;                     // 0: no request,               1: exist pending ocmf
+        unsigned int OcmfNeedUpload:1;                  // 0: no request,               1: ocmf need upload
+        unsigned int OcmfUploading:1;                   // 0: no request,               1: ocmf is uploading
+        unsigned int res:29;
+    }bits;
+}SysOcmfFlag;
+
+typedef struct
+{
+    int SysOcmfIndex;
+    char SysOcmfTxId[36];
+    char SysOcmfPublicKey[200];
+    char SysOcmfInfo[2048];
+    SysOcmfFlag SysOcmfFlag;
+    OCMFInfoData GunOcmf[MAX_GUN_QUANTITY];
+}SysOCMFInfoData;
 // ************************************************************************************************* //
 // ************************************************************************************************* //
 
 
 typedef struct
 typedef struct
@@ -1584,6 +1739,7 @@ typedef struct
     GunError GunError[MAX_GUN_QUANTITY];
     GunError GunError[MAX_GUN_QUANTITY];
     OutputLimitation OutputLimit;
     OutputLimitation OutputLimit;
     AllBillInfoData AllBill;
     AllBillInfoData AllBill;
+    SysOCMFInfoData OcmfInfo;
 }ChargerInfoData;
 }ChargerInfoData;
 
 
 #endif /* CONFIG_H_ */
 #endif /* CONFIG_H_ */

+ 7 - 7
EVSE/Projects/DO360/Apps/FactoryConfig.c

@@ -252,14 +252,14 @@ int main(int argc,char *argv[])
 	strcpy((char *) SysConfig.OcppServerURL, "");
 	strcpy((char *) SysConfig.OcppServerURL, "");
 	strcpy((char *) SysConfig.ChargeBoxId, "");
 	strcpy((char *) SysConfig.ChargeBoxId, "");
 
 
-	if(SysConfig.ModelName[12] == 'P' && SysConfig.ModelName[13] == 'H')
-	{
-	    strcpy((char *) SysConfig.MaintainServerURL, "wss://ocpp.phihong.com.tw:2013/");
-	}
-	else
-	{
+	//if(SysConfig.ModelName[12] == 'P' && SysConfig.ModelName[13] == 'H')
+	//{
+	//    strcpy((char *) SysConfig.MaintainServerURL, "wss://ocpp.phihong.com.tw:2013/");
+	//}
+	//else
+	//{
 	    strcpy((char *) SysConfig.MaintainServerURL, "");
 	    strcpy((char *) SysConfig.MaintainServerURL, "");
-	}
+	//}
 
 
 	SysConfig.LedInfo.Intensity = 2;
 	SysConfig.LedInfo.Intensity = 2;
 
 

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

@@ -305,9 +305,9 @@ void ReceiveDataFromCanBus()
                     case PSU_RCmd_ModuleInputVoltage:
                     case PSU_RCmd_ModuleInputVoltage:
                     {
                     {
                         // 回傳三向輸入電壓
                         // 回傳三向輸入電壓
-                        short abVol = ((frame.data[0] << 8) + frame.data[1]) / 10;
-                        short bcVol = ((frame.data[2] << 8) + frame.data[3]) / 10;
-                        short caVol = ((frame.data[4] << 8) + frame.data[5]) / 10;
+                        short abVol = ((frame.data[0] << 8) + frame.data[1]);
+                        short bcVol = ((frame.data[2] << 8) + frame.data[3]);
+                        short caVol = ((frame.data[4] << 8) + frame.data[5]);
 
 
                         return_input_vol(address, abVol, bcVol, caVol);
                         return_input_vol(address, abVol, bcVol, caVol);
                     }
                     }

+ 9 - 1
EVSE/Projects/DO360/Apps/Makefile

@@ -13,7 +13,7 @@ Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 all: CopyFile apps Clean
 all: CopyFile apps Clean
 #apps: Module_CSU Module_EvComm Module_EventLogging Module_InternalComm Module_LcmControl Module_PrimaryComm Module_PsuComm 
 #apps: Module_CSU Module_EvComm Module_EventLogging Module_InternalComm Module_LcmControl Module_PrimaryComm Module_PsuComm 
 # ReadCmdline kill.sh
 # ReadCmdline kill.sh
-apps: Common MainTask CabinetParallel SelfTestTask AuthorizeTask LedIndication EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask InfyGroup_PsuCommObj PhGroup_PsuCommObj PsuCommTask PhPsuCommTask ReadCmdlineTask FactoryConfigApp OtherTools
+apps: Common MainTask CabinetParallel SelfTestTask AuthorizeTask LedIndication EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask InfyGroup_PsuCommObj PhGroup_PsuCommObj PsuCommTask PhPsuCommTask ReadCmdlineTask DispenserDiagnostics FactoryConfigApp OtherTools
 
 
 Common:
 Common:
 	rm -f Common.o
 	rm -f Common.o
@@ -113,6 +113,12 @@ ReadCmdlineTask:
 	$(CC) -o ReadCmdline ReadCmdline.o Common.o ../../../Modularization/libModule_RatedCurrent.a -lrt -lm
 	$(CC) -o ReadCmdline ReadCmdline.o Common.o ../../../Modularization/libModule_RatedCurrent.a -lrt -lm
 	cp -f ReadCmdline ../Images/root
 	cp -f ReadCmdline ../Images/root
 
 
+DispenserDiagnostics:
+	rm -f Module_Diagnostics; 
+	$(CC) -D $(Project) -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_Diagnostics.o Module_Diagnostics.c
+	$(CC) -o Module_Diagnostics Module_Diagnostics.o Common.o -lrt -lm
+	cp -f Module_Diagnostics ../Images/root
+
 UnsafetyOutputTool:
 UnsafetyOutputTool:
 	rm -f UnsafetyOutputTask; 
 	rm -f UnsafetyOutputTask; 
 	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -O0 -g3 -Wall -c -fmessage-length=0 -o OutputTask.o OutputTask.c
 	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -O0 -g3 -Wall -c -fmessage-length=0 -o OutputTask.o OutputTask.c
@@ -157,6 +163,8 @@ CleanExecute:
 	rm -f Module_LcmControl
 	rm -f Module_LcmControl
 	rm -f Module_PrimaryComm
 	rm -f Module_PrimaryComm
 	rm -f Module_PsuComm
 	rm -f Module_PsuComm
+	rm -f Module_PsuComm_PH
 	rm -f ReadCmdline
 	rm -f ReadCmdline
+	rm -f Module_Diagnostics
 	rm -f FactoryConfig
 	rm -f FactoryConfig
 	rm -f UnsafetyOutputTask
 	rm -f UnsafetyOutputTask

+ 444 - 0
EVSE/Projects/DO360/Apps/Module_Diagnostics.c

@@ -0,0 +1,444 @@
+/*
+ * Module_Diagnostics.c
+ *
+ *  Created on: 2022年12月12日
+ *      Author: 7978
+ */
+
+#include    <sys/time.h>
+#include    <sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include    <sys/types.h>
+#include    <sys/ioctl.h>
+#include    <sys/socket.h>
+#include    <sys/ipc.h>
+#include    <sys/shm.h>
+#include    <sys/shm.h>
+#include    <sys/mman.h>
+#include    <linux/wireless.h>
+#include    <arpa/inet.h>
+#include    <netinet/in.h>
+
+#include    <unistd.h>
+#include    <stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include    <errno.h>
+#include    <string.h>
+#include    <time.h>
+#include    <ctype.h>
+#include    <ifaddrs.h>
+#include    <math.h>
+#include    <stdbool.h>
+#include    "../../define.h"
+#include    "Config.h"
+#include    "Common.h"
+#include    "Module_EvComm.h"
+
+struct SysConfigAndInfo         *ShmSysConfigAndInfo;
+struct StatusCodeData           *ShmStatusCodeData;
+struct PrimaryMcuData           *ShmPrimaryMcuData;
+struct PsuData                  *ShmPsuData;
+struct RelayModuleData          *ShmRelayModuleData[2];
+struct FanModuleData            *ShmFanModuleData;
+struct LedModuleData            *ShmLedModuleData;
+ChargerInfoData                 *ShmChargerInfo;
+struct OCPP16Data               *ShmOCPP16Data;
+struct OCPP20Data               *ShmOCPP20Data;
+struct OCPP16Data               *ShmOCPP16DataPH;
+
+int InitSysConfigAndInfoShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmSysConfigAndInfo
+    if((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitStatusCodeShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmStatusCodeData
+    if((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitPrimaryMcuShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmPrimaryMcuData
+    if((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), 0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitPsuShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmPsuData
+    if((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitRelayModuleShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmRelayModuleData
+    if((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmRelayModuleData[0] = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitRelay2ModuleShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmRelayModuleData
+    if((MeterSMId = shmget(ShmRelay2BdKey, sizeof(struct RelayModuleData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmRelayModuleData[1] = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitFanModuleShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmFanModuleData
+    if((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitLedModuleShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmLedModuleData
+    if((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmLedModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitChargerInfoShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmChargerInfo
+    if((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData),  0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmChargerInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitOCPP16ShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmOCPP16Data
+    if((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitOCPP16PHShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmOCPP16Data
+    if((MeterSMId = shmget(ShmOcppPHModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmOCPP16DataPH = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitOCPP20ShareMemory(void)
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //initial ShmOCPP20Data
+    if((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), 0777)) < 0)
+    {
+        result = FAIL;
+    }
+    else if((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+int InitShareMemory(void)
+{
+    int result = PASS;
+
+    //initial ShmSysConfigAndInfo
+    if(InitSysConfigAndInfoShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmStatusCodeData
+    if(InitStatusCodeShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmPrimaryMcuData
+    if(InitPrimaryMcuShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmPsuData
+    if(InitPsuShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmRelayModuleData
+    if(InitRelayModuleShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    if(InitRelay2ModuleShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmFanModuleData
+    if(InitFanModuleShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmLedModuleData
+    if(InitLedModuleShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmChargerInfo
+    if(InitChargerInfoShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmOCPP16Data
+    if(InitOCPP16ShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    if(InitOCPP16PHShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    //initial ShmOCPP20Data
+    if(InitOCPP20ShareMemory() == FAIL)
+    {
+        result = FAIL;
+    }
+
+    return result;
+}
+
+// ./Module_Diagnostics X AAA.AAA.AAA.AAA
+// Dispenser ID: X, start from 1 ~ 4
+// Dispenser IP: AAA.AAA.AAA.AAA
+int main(int argc, char *argv[])
+{
+    int success = FAIL;
+    bool _find = false;
+    int _dispenserId = 0;
+    char _address[128];
+    char dispenserStr[64];
+
+    memset(_address, 0x00, sizeof(_address));
+    memset(dispenserStr, 0x00, sizeof(dispenserStr));
+
+    if(InitShareMemory() == FAIL)
+    {
+        LOG_ERROR("InitShareMemory NG");
+        return FAIL;
+    }
+
+    if(argc == 3)
+    {
+        _dispenserId = atoi(argv[1]);
+        strcpy(_address, argv[2]);
+
+        if(_dispenserId > 0)
+        {
+            for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
+            {
+                if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].Status == _CNS_DispenserMatched)
+                {
+                    if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].IpAddress == inet_addr(_address) &&
+                        ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].DispenserIndex == (_dispenserId - 1))
+                    {
+                        _find = true;
+                    }
+                }
+            }
+        }
+
+        if(_find)
+        {
+            sprintf(dispenserStr, "Dispenser %d ", _dispenserId);
+            ShmChargerInfo->Control.Diagnostics.DispenserDiagnostics[_dispenserId - 1].bits.Confirm = ShmChargerInfo->Control.Diagnostics.DispenserDiagnostics[_dispenserId - 1].bits.Request;
+        }
+        LOG_INFO("Set Diagnostics Request to %s[%s]", dispenserStr, _address);
+
+        char cmdBuf[512] = {0};
+        sprintf(cmdBuf, "curl -k -X POST --data \"logCnt=2\" https://%s/log_download_action.php", _address);
+        if(system(cmdBuf) == 0)
+        {
+            success = PASS;
+        }
+
+        LOG_INFO("%s[%s] Latest log file is %s", dispenserStr, _address, success == PASS ? "OK" : "NG");
+
+        if(success == PASS)
+        {
+            struct timeb  SeqEndTime;
+            struct tm *tm;
+            ftime(&SeqEndTime);
+            SeqEndTime.time = time(NULL);
+            tm=localtime(&SeqEndTime.time);
+            char _fileName[64];
+
+            if(_find)
+            {
+                sprintf(_fileName, "%d", _dispenserId);
+            }
+            else
+            {
+                sprintf(_fileName, "[%02d.%02d]", tm->tm_mon + 1, tm->tm_mday);
+            }
+
+            sprintf((char*)cmdBuf,"ftpget -u root -p y42j/4cj84 %s \"/Storage/SystemLog/[%04d.%02d]Dispenser%sLog.zip\" /mnt/log.zip",
+                _address, tm->tm_year + 1900, tm->tm_mon + 1, _fileName);
+
+            if(system(cmdBuf) != 0)
+            {
+                success = FAIL;
+            }
+
+            LOG_INFO("Diagnostics %s[%s] %s", dispenserStr, _address, success == PASS ? "OK" : "NG");
+            if(success)
+            {
+                ShmChargerInfo->Control.Diagnostics.DispenserDiagnostics[_dispenserId - 1].bits.Completed = ShmChargerInfo->Control.Diagnostics.DispenserDiagnostics[_dispenserId - 1].bits.Confirm;
+            }
+        }
+    }
+    else
+    {
+        LOG_INFO("Diagnostics input parameter error!");
+    }
+
+    return success;
+}
+

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

@@ -1292,16 +1292,36 @@ void UserIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char r
 void ChargingPermissionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
 void ChargingPermissionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
 {
 {
 	struct PACKET_STRUCTURE sendBuffer;
 	struct PACKET_STRUCTURE sendBuffer;
+	bool _NormalStop = true;
 
 
 	memset(&sendBuffer, 0x00, sizeof(sendBuffer));
 	memset(&sendBuffer, 0x00, sizeof(sendBuffer));
 	sendBuffer.Header.se = packet->Header.se;
 	sendBuffer.Header.se = packet->Header.se;
 	sendBuffer.Header.id = packet->Header.id;
 	sendBuffer.Header.id = packet->Header.id;
 	sendBuffer.Header.op = _Header_Response;
 	sendBuffer.Header.op = _Header_Response;
-	sendBuffer.Header.len = 3;
+	sendBuffer.Header.len = 9;
 	sendBuffer.Payload.reg = _Reg_Charging_Permission;
 	sendBuffer.Payload.reg = _Reg_Charging_Permission;
 	sendBuffer.Payload.data[0] = result == _DAS_Wait ? _R_NG : _R_OK;
 	sendBuffer.Payload.data[0] = result == _DAS_Wait ? _R_NG : _R_OK;
 	sendBuffer.Payload.data[1] = result == _DAS_Allowed ? _PS_Permitted : _PS_NotPermitted;
 	sendBuffer.Payload.data[1] = result == _DAS_Allowed ? _PS_Permitted : _PS_NotPermitted;
 
 
+	if(result == _DAS_NotAllowed)
+	{
+	    if(strcmp((char *)chargingInfo[packet->Header.id - 1]->ConnectorAlarmCode, "") != EQUAL)
+	    {
+	        memcpy((char *)&sendBuffer.Payload.data[2], (char *)chargingInfo[packet->Header.id - 1]->ConnectorAlarmCode, 6);
+	        _NormalStop = false;
+	    }
+	    else if(strcmp((char *)chargingInfo[packet->Header.id - 1]->EvConnAlarmCode, "") != EQUAL)
+	    {
+	        memcpy((char *)&sendBuffer.Payload.data[2], (char *)chargingInfo[packet->Header.id - 1]->EvConnAlarmCode, 6);
+	        _NormalStop = false;
+	    }
+	}
+
+	if(_NormalStop)
+	{
+	    memcpy((char *)&sendBuffer.Payload.data[2], "000000", 6);
+	}
+
 	SendPacket(socket, &sendBuffer);
 	SendPacket(socket, &sendBuffer);
 }
 }
 
 
@@ -2725,6 +2745,21 @@ void ParkingBillResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
     SendPacket(socket, &sendBuffer);
     SendPacket(socket, &sendBuffer);
 }
 }
 
 
+void WriteOcmfInfoResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+{
+    struct PACKET_STRUCTURE sendBuffer;
+
+    memset(&sendBuffer, 0x00, sizeof(sendBuffer));
+    sendBuffer.Header.se = packet->Header.se;
+    sendBuffer.Header.id = packet->Header.id;
+    sendBuffer.Header.op = _Header_Response;
+    sendBuffer.Header.len = 2;
+    sendBuffer.Payload.reg = _Reg_OCMF_Info;
+    sendBuffer.Payload.data[0] = result;
+
+    SendPacket(socket, &sendBuffer);
+}
+
 BOOL FindConnectorID(unsigned char dispenserIndex, unsigned char id)
 BOOL FindConnectorID(unsigned char dispenserIndex, unsigned char id)
 {
 {
 	BOOL find = false;
 	BOOL find = false;
@@ -2804,6 +2839,8 @@ void ConnectorPhysicalLimitBindingHandler(unsigned char connectorIndex, unsigned
             //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CCS_MAX_PHYSICAL_VOLTAGE;
             //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CCS_MAX_PHYSICAL_VOLTAGE;
             //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CCS_LIQUID_V_F_MAX_CURRENT;
             //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CCS_LIQUID_V_F_MAX_CURRENT;
             // Derating Mode
             // Derating Mode
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CCS_MAX_PHYSICAL_VOLTAGE;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CCS_LIQUID_V_F_MAX_CURRENT;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.isNeedDerating = YES;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.isNeedDerating = YES;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.deratingIndex = 0;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.deratingIndex = 0;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.deratingTargetCurrent[0] = CCS_LIQUID_V_F_MAX_CURRENT;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].GeneralChargingData.deratingByConnOtp.deratingTargetCurrent[0] = CCS_LIQUID_V_F_MAX_CURRENT;
@@ -3347,6 +3384,11 @@ BOOL ConnectorStateHandler(struct PACKET_STRUCTURE *packet, unsigned char dispen
                                 chargingInfo[packet->Header.id - 1]->ReservationId = -1;
                                 chargingInfo[packet->Header.id - 1]->ReservationId = -1;
                                 LOG_INFO("*********** Connector %d Clean ReservationId ***********\n", packet->Header.id);
                                 LOG_INFO("*********** Connector %d Clean ReservationId ***********\n", packet->Header.id);
                             }
                             }
+                            else if(chargingInfo[packet->Header.id - 1]->SystemStatus == S_AUTHORIZING)
+                            {
+                                LOG_INFO("*********** Connector %d Normal Stop ***********\n", packet->Header.id);
+                                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.NormalStopRequest = true;
+                            }
                         }
                         }
                         else if(chargingInfo[packet->Header.id - 1]->SystemStatus == S_AUTHORIZING)
                         else if(chargingInfo[packet->Header.id - 1]->SystemStatus == S_AUTHORIZING)
                         {
                         {
@@ -4383,6 +4425,72 @@ unsigned char ReadParkingBillHandler(struct PACKET_STRUCTURE *packet, int dispen
     return false;
     return false;
 }
 }
 
 
+unsigned char WriteOcmfInfoHandler(struct PACKET_STRUCTURE *packet, int dispenserIndex)
+{
+    BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+    int gun = 0;
+    unsigned int ocfmCrc = 0;
+    char txId[37], publicKey[201];
+    char fileName[256];
+    unsigned int _calCrc32 = 0;
+
+    if(find)
+    {
+        gun = packet->Header.id - 1;
+
+        if(ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfFlag.bits.OcmfReceived)
+        {
+            LOG_INFO("Gun %d last OCMF info is still handling", packet->Header.id);
+            return false;
+        }
+
+        memset(txId, 0x00, sizeof(txId));
+        memcpy(txId, &packet->Payload.data[0], sizeof(txId) - 1);
+
+        ocfmCrc = (packet->Payload.data[36] << 24) +
+                  (packet->Payload.data[37] << 16) +
+                  (packet->Payload.data[38] << 8) +
+                  (packet->Payload.data[39]);
+
+        memset(publicKey, 0x00, sizeof(publicKey));
+        memcpy(publicKey, &packet->Payload.data[40], sizeof(publicKey) - 1);
+
+        sprintf(fileName, "/mnt/Gun_%d_%s_OCMF", packet->Header.id, txId);
+
+        if(access(fileName, F_OK) == 0)
+        {
+            _calCrc32 = getFileCrc32(fileName);
+
+            if(_calCrc32 == ocfmCrc)
+            {
+                memset(ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfTxId, 0x00, sizeof(ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfTxId));
+                memset(ShmChargerInfo->OcmfInfo.GunOcmf[gun].PublicKey, 0x00, sizeof(ShmChargerInfo->OcmfInfo.GunOcmf[gun].PublicKey));
+                memcpy(&ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfTxId, txId, sizeof(ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfTxId));
+                memcpy(&ShmChargerInfo->OcmfInfo.GunOcmf[gun].PublicKey, publicKey, sizeof(ShmChargerInfo->OcmfInfo.GunOcmf[gun].PublicKey));
+                LOG_INFO("Gun %d OCMF info [%s] received, crc is 0x%X", packet->Header.id, fileName, _calCrc32);
+                ShmChargerInfo->OcmfInfo.GunOcmf[gun].OcmfFlag.bits.OcmfReceived = true;
+                return true;
+            }
+            else
+            {
+                LOG_INFO("Gun %d OCMF info received, but crc not match, crc: 0x%8X != 0x%8X", packet->Header.id, ocfmCrc, _calCrc32);
+                char cmdBuf[256] = {0};
+                sprintf(cmdBuf, "rm -f %s", fileName);
+                system(cmdBuf);
+
+                return false;
+            }
+        }
+        else
+        {
+            LOG_INFO("Gun %d OCMF info received, but file[%s] not exist.", packet->Header.id, fileName);
+            return false;
+        }
+    }
+
+    return false;
+}
+
 void DisableConnector(unsigned char dispenserIndex)
 void DisableConnector(unsigned char dispenserIndex)
 {
 {
 	for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorQuantity; i++)
 	for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorQuantity; i++)
@@ -4909,6 +5017,16 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
                         }
                         }
                         ParkingBillResponse(socketFd, &receiveBuffer, ackResult);
                         ParkingBillResponse(socketFd, &receiveBuffer, ackResult);
                     }
                     }
+
+                    // Reg: 0x29 _Reg_OCMF_Info
+                    if(receiveBuffer.Header.op == _Header_Write && receiveBuffer.Payload.reg == _Reg_OCMF_Info)
+                    {
+                        if(WriteOcmfInfoHandler(&receiveBuffer, dispenserIndex))
+                        {
+                            ackResult = _R_OK;
+                        }
+                        WriteOcmfInfoResponse(socketFd, &receiveBuffer, ackResult);
+                    }
 				}
 				}
 
 
 				// clean timeout
 				// clean timeout

+ 2 - 1
EVSE/Projects/DO360/Apps/Module_EvComm.h

@@ -108,7 +108,8 @@ enum PAYLOAD_REGISTER
     _Reg_ChargingBill               = 0x26,
     _Reg_ChargingBill               = 0x26,
     _Reg_ParkingStatus              = 0x27,
     _Reg_ParkingStatus              = 0x27,
     _Reg_ParkingBill                = 0x28,
     _Reg_ParkingBill                = 0x28,
-    _Reg_None                       = 0x29,
+    _Reg_OCMF_Info                  = 0x29,
+    _Reg_None                       = 0x2A,
 };
 };
 
 
 enum Response_Result
 enum Response_Result

+ 36 - 24
EVSE/Projects/DO360/Apps/Module_EventLogging.c

@@ -30,6 +30,8 @@
 #include	"../../define.h"
 #include	"../../define.h"
 #include    "Common.h"
 #include    "Common.h"
 
 
+#define LOG_EVENT(format, args...) StoreEventLogMsg("[%s:%4d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+
 struct network_previous_status
 struct network_previous_status
 {
 {
     int     rssiWifi;
     int     rssiWifi;
@@ -53,36 +55,44 @@ struct network_previous_status  netPreviousStatus;
 sqlite3 *localDb;
 sqlite3 *localDb;
 sqlite3 *networkDb;
 sqlite3 *networkDb;
 
 
-int DiffTimeb(struct timeb ST, struct timeb ET)
+int StoreEventLogMsg(const char *fmt, ...)
 {
 {
-	//return milli-second
-	unsigned int StartTime,StopTime;
-
-	StartTime=(unsigned int)ST.time;
-	StopTime=(unsigned int)ET.time;
-	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
-}
-
-//=================================
-// Common routine
-//=================================
-char* getTimeString(void)
-{
-	char *result=malloc(21);
-	time_t timep;
-	struct tm *p;
-	time(&timep);
-	p=gmtime(&timep);
-
-	sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec);
-
-	return result;
+    char Buf[4096+256];
+    char buffer[4096];
+    va_list args;
+    struct timeb  SeqEndTime;
+    struct tm *tm;
+
+    va_start(args, fmt);
+    int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+    va_end(args);
+
+    memset(Buf,0,sizeof(Buf));
+    ftime(&SeqEndTime);
+    SeqEndTime.time = time(NULL);
+    tm=localtime(&SeqEndTime.time);
+
+    sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/EventLog/[%04d.%02d]%s_%s_EventLog",
+        tm->tm_year + 1900,
+        tm->tm_mon + 1,
+        tm->tm_mday,
+        tm->tm_hour,
+        tm->tm_min,
+        tm->tm_sec,
+        SeqEndTime.millitm,
+        buffer,
+        tm->tm_year+1900,tm->tm_mon+1,
+        ShmSysConfigAndInfo->SysConfig.ModelName,
+        ShmSysConfigAndInfo->SysConfig.SerialNumber);
+    system(Buf);
+
+    return rc;
 }
 }
 
 
 //==========================================
 //==========================================
 // Init all share memory
 // Init all share memory
 //==========================================
 //==========================================
-int InitShareMemory()
+int InitShareMemory(void)
 {
 {
 	int result = PASS;
 	int result = PASS;
 	int MeterSMId;
 	int MeterSMId;
@@ -514,6 +524,8 @@ int main(void)
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFault = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = YES;
 
 
 	// InfoEvents disable mask
 	// InfoEvents disable mask
 	StatusCodeDisableMask.InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = YES;
 	StatusCodeDisableMask.InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = YES;

+ 113 - 2
EVSE/Projects/DO360/Apps/Module_PrimaryComm.c

@@ -33,8 +33,11 @@
 #include    "Config.h"
 #include    "Config.h"
 #include    "Common.h"
 #include    "Common.h"
 
 
-#define COMM_FAIL_COUNT         10
-#define STATE_CHANGE_COUNT      3
+#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_STOP       1               // unit: 1s
 
 
 typedef unsigned char 		byte;
 typedef unsigned char 		byte;
 
 
@@ -487,6 +490,109 @@ int InitComPort()
 	return fd;
 	return fd;
 }
 }
 
 
+int preTiltSensorStep = _TILT_SENSOR_NONE;
+struct timespec _tiltSensor_time;
+
+void CheckTiltSensor(void)
+{
+    if(ShmPrimaryMcuData->InputDet.bits.AcContactorDetec)
+    {
+        int step = ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep;
+
+        switch(step)
+        {
+            case _TILT_SENSOR_NONE:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                }
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT;
+                break;
+            case _TILT_SENSOR_WAIT:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    GetClockTime(&_tiltSensor_time);
+                }
+                if((GetTimeoutValue(_tiltSensor_time) / uSEC_VAL) > TILT_SENSOR_WAIT_TIME)
+                {
+                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_START;
+                }
+                break;
+            case _TILT_SENSOR_START:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    LOG_INFO("Tilt sensor self test start!");
+                }
+                ShmPrimaryMcuData->OutputDrv.bits.SystemLed3Drv = true;
+                ShmPrimaryMcuData->OutputDrv.bits.SystemLed4Drv = true;
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT_RESPONSE;
+                break;
+            case _TILT_SENSOR_WAIT_RESPONSE:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    GetClockTime(&_tiltSensor_time);
+                }
+                if((GetTimeoutValue(_tiltSensor_time) / uSEC_VAL) > TILT_SENSOR_WAIT_RESPONSE)
+                {
+                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_OUTCOME;
+                }
+                break;
+            case _TILT_SENSOR_OUTCOME:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    //LOG_INFO("Tilt sensor self test check");
+                }
+                LOG_INFO("Tilt sensor self test result [%s]", ShmPrimaryMcuData->InputDet.bits.DoorOpen ? "OK" : "NG");
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorFail = ShmPrimaryMcuData->InputDet.bits.DoorOpen ? NO : YES;
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_STOP;
+                break;
+            case _TILT_SENSOR_STOP:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    //LOG_INFO("Tilt sensor self test stop!");
+                }
+                ShmPrimaryMcuData->OutputDrv.bits.SystemLed3Drv = false;
+                ShmPrimaryMcuData->OutputDrv.bits.SystemLed4Drv = false;
+                ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_WAIT_STOP;
+                break;
+            case _TILT_SENSOR_WAIT_STOP:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    GetClockTime(&_tiltSensor_time);
+                }
+                if((GetTimeoutValue(_tiltSensor_time) / uSEC_VAL) > TILT_SENSOR_WAIT_STOP)
+                {
+                    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_FINISH;
+                }
+                break;
+            case _TILT_SENSOR_FINISH:
+                if(preTiltSensorStep != step)
+                {
+                    preTiltSensorStep = step;
+                    LOG_INFO("Tilt sensor self test done!");
+                }
+                break;
+        }
+    }
+    else
+    {
+        if(ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep != _TILT_SENSOR_NONE &&
+            ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep != _TILT_SENSOR_FINISH)
+        {
+            ShmPrimaryMcuData->OutputDrv.bits.SystemLed3Drv = false;
+            ShmPrimaryMcuData->OutputDrv.bits.SystemLed4Drv = false;
+            LOG_INFO("Tilt sensor self test reset");
+        }
+        ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_NONE;
+    }
+}
+
 int main(void)
 int main(void)
 {
 {
 	if(InitShareMemory() == FAIL)
 	if(InitShareMemory() == FAIL)
@@ -556,6 +662,11 @@ int main(void)
                 GetInputGpioStatus();
                 GetInputGpioStatus();
                 //LOG_INFO("Input Status: %02X %02X", ShmPrimaryMcuData->InputDet.InputDetValue[1], ShmPrimaryMcuData->InputDet.InputDetValue[0]);
                 //LOG_INFO("Input Status: %02X %02X", ShmPrimaryMcuData->InputDet.InputDetValue[1], ShmPrimaryMcuData->InputDet.InputDetValue[0]);
 
 
+                if(ShmChargerInfo->Control.CustomizedInfo.Flag.bits.TiltSensorEnable)
+                {
+                    CheckTiltSensor();
+                }
+
                 SetOutputGpio(ShmPrimaryMcuData->OutputDrv.OutputDrvValue[0]);
                 SetOutputGpio(ShmPrimaryMcuData->OutputDrv.OutputDrvValue[0]);
             }
             }
 	    }
 	    }

+ 321 - 56
EVSE/Projects/DO360/Apps/Module_PsuComm.c

@@ -85,8 +85,10 @@
 #define MAX_DIFF_POWER_TO_DERATING      5           // unit: 1kw
 #define MAX_DIFF_POWER_TO_DERATING      5           // unit: 1kw
 #define MAX_DIFF_POWER_TO_EXTEND        3           // unit: 1kw
 #define MAX_DIFF_POWER_TO_EXTEND        3           // unit: 1kw
 #define MIN_DIFF_PHYSICAL_POWER         3           // unit: 1kw
 #define MIN_DIFF_PHYSICAL_POWER         3           // unit: 1kw
+#define MIN_DIFF_CONFIG_POWER           3           // unit: 1kw
 #define PSU_DEBUG_MSG                   0
 #define PSU_DEBUG_MSG                   0
 #define ENABLE_SMOOTH_DERATING          1
 #define ENABLE_SMOOTH_DERATING          1
+#define PSU_INDICATION_TIME             10          // unit: 1s
 
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 struct StatusCodeData 			*ShmStatusCodeData;
@@ -146,6 +148,8 @@ unsigned char _VoltageResumeCnt[MAX_GROUP_QUANTITY];
 
 
 unsigned char _GunIndexOfPrioritySequence[MAX_GROUP_QUANTITY];
 unsigned char _GunIndexOfPrioritySequence[MAX_GROUP_QUANTITY];
 PsuStatusInfo _LocalPsuStatus[MAX_PSU_MODULE_QUANTITY];
 PsuStatusInfo _LocalPsuStatus[MAX_PSU_MODULE_QUANTITY];
+bool _Psu_Indication_Enable[MAX_PSU_MODULE_QUANTITY];
+int _Psu_Indication_Count[MAX_PSU_MODULE_QUANTITY];
 
 
 int GetPsuModuleQuantity(unsigned char group);
 int GetPsuModuleQuantity(unsigned char group);
 
 
@@ -508,6 +512,51 @@ void AbnormalStopAnalysis(byte gun_index, int errCode)
 	}
 	}
 }
 }
 
 
+// return single psu alarm status: PsuStatusInfo
+unsigned int InfyPwrStateAnalysis(int psu_index, unsigned char state_0, unsigned char state_1, unsigned char state_2)
+{
+    bool _changed = false;
+    PsuStatusInfo _alarmStatus;
+
+    _alarmStatus.StatusVal = 0;
+
+    if(ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0] != state_0 ||
+        (ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1] & 0xFE) != (state_1 & 0xFE) ||
+        (ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2] & 0x7F) != (state_2 & 0x7F))
+    {
+        _changed = true;
+    }
+
+    InfyPsuStateFlagInfo _infyState;
+
+    _infyState.StateVal[0] = state_0;
+    _infyState.StateVal[1] = state_1;
+    _infyState.StateVal[2] = state_2;
+
+    if(_infyState.bits.OutputShort ||
+       _infyState.bits.PsuFault ||
+       _infyState.bits.FanFault ||
+       _infyState.bits.PsuProtect ||
+       _infyState.bits.FanFault ||
+       _infyState.bits.OverTemperature ||
+       _infyState.bits.OutputOverVoltage ||
+       _infyState.bits.CanCommInterrupt ||
+       _infyState.bits.PsuIdRepetition ||
+       _infyState.bits.InputPhaseLost ||
+       _infyState.bits.InputUnderVoltage ||
+       _infyState.bits.InputOverVoltage)
+    {
+        _alarmStatus.bits.Fault = true;
+    }
+
+    ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed = _changed;
+    ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0] = state_0;
+    ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1] = state_1;
+    ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2] = state_2;
+
+    return _alarmStatus.StatusVal;
+}
+
 //=================================
 //=================================
 // Callback Function
 // Callback Function
 //=================================
 //=================================
@@ -664,7 +713,8 @@ void GetInfyPwrAlarmFlagCallback(byte address, byte state_2, byte state_1, byte
 {
 {
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
 
 
-    if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
+    if(ShmPsuData->Work_Step < Get_PSU_LOCATION || address >= ShmPsuData->SystemInitialPsuQuantity ||
+        !ShmPsuPosition->PsuLocationInit)
     {
     {
         return;
         return;
     }
     }
@@ -677,10 +727,11 @@ void GetInfyPwrAlarmFlagCallback(byte address, byte state_2, byte state_1, byte
         return;
         return;
     }
     }
 
 
-    if(ShmPsuPosition->PsuLocationInit)
-    {
+    unsigned int _alarmStatus = 0;
 
 
-    }
+    _alarmStatus = InfyPwrStateAnalysis(address, state_0, state_1, state_2);
+
+    GetAlarmStatusCallback(address, _alarmStatus);
 }
 }
 
 
 void GetPhPwrAlarmFlagCallback(byte address, unsigned int status, unsigned int alarm_1, unsigned int alarm_0)
 void GetPhPwrAlarmFlagCallback(byte address, unsigned int status, unsigned int alarm_1, unsigned int alarm_0)
@@ -997,6 +1048,25 @@ void GetPfcFwCallback(byte address, char *pfcSwVer)
 // no using -- GetInputVoltageCallback
 // no using -- GetInputVoltageCallback
 void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
 void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
 {
 {
+    ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
+
+    if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
+        !ShmPsuPosition->PsuLocationInit)
+    {
+        return;
+    }
+
+    int group = FindTargetGroup(address);
+    int gIndex = FindGroupIndex(address);
+
+    if(group < 0 || gIndex < 0)
+    {
+        return;
+    }
+
+    ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL1 = vol1;
+    ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL2 = vol2;
+    ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL3 = vol3;
 }
 }
 // no using -- GetInputVoltageCallback End
 // no using -- GetInputVoltageCallback End
 
 
@@ -1367,7 +1437,7 @@ void GetErrorRecordCallback(byte psu_index, byte count_down, byte *error_record)
         if(error_record[i] != 0)
         if(error_record[i] != 0)
         {
         {
             err_cnt++;
             err_cnt++;
-            if(ShmPsuPosition->SinglePsuError[psu_index].PsuError[i] != error_record[i] || _change)
+            if(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError[i] != error_record[i] || _change)
             {
             {
                 _change = true;
                 _change = true;
             }
             }
@@ -1380,16 +1450,16 @@ void GetErrorRecordCallback(byte psu_index, byte count_down, byte *error_record)
 
 
     if(_change)
     if(_change)
     {
     {
-        memset(ShmPsuPosition->SinglePsuError[psu_index].PsuError, 0x00, sizeof(ShmPsuPosition->SinglePsuError[psu_index].PsuError));
-        memcpy(ShmPsuPosition->SinglePsuError[psu_index].PsuError, error_record, err_cnt);
+        memset(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError, 0x00, sizeof(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError));
+        memcpy(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError, error_record, err_cnt);
     }
     }
     else
     else
     {
     {
-        _change = ShmPsuPosition->SinglePsuError[psu_index].ErrorCount != err_cnt ? true : false;
+        _change = ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount != err_cnt ? true : false;
     }
     }
 
 
-    ShmPsuPosition->SinglePsuError[psu_index].ErrorCount = err_cnt;
-    ShmPsuPosition->SinglePsuError[psu_index].ErrFlag.bits.Changed |= _change;
+    ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount = err_cnt;
+    ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed |= _change;
 }
 }
 
 
 //==========================================
 //==========================================
@@ -1400,10 +1470,10 @@ void GetErrorRecordCallback(byte psu_index, byte count_down, byte *error_record)
 void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
 void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
 		unsigned short outputCur_s, unsigned short outputPower, unsigned char Temperature)
 		unsigned short outputCur_s, unsigned short outputPower, unsigned char Temperature)
 {
 {
-    ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
-
     return;
     return;
 
 
+    ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
+
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
         !ShmPsuPosition->PsuLocationInit)
         !ShmPsuPosition->PsuLocationInit)
     {
     {
@@ -1427,6 +1497,8 @@ void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
 void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
 void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
 		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
 		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
 {
 {
+    return;
+
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
 
 
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
@@ -1460,6 +1532,8 @@ void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char st
 void GetModuleInputCallback(byte address, unsigned short inputR,
 void GetModuleInputCallback(byte address, unsigned short inputR,
 		unsigned short inputS, unsigned short inputT)
 		unsigned short inputS, unsigned short inputT)
 {
 {
+    return;
+
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
     ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
 
 
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
     if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
@@ -1605,8 +1679,12 @@ void InitialPsuData(void)
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFault = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO;
 
 
     memset(_LocalPsuStatus, 0x00, sizeof(_LocalPsuStatus));
     memset(_LocalPsuStatus, 0x00, sizeof(_LocalPsuStatus));
+    memset(_Psu_Indication_Enable, 0x00, sizeof(_Psu_Indication_Enable));
+    memset(_Psu_Indication_Count, 0x00, sizeof(_Psu_Indication_Count));
     memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR));
     memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR));
     memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND));
     memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND));
 }
 }
@@ -2760,15 +2838,33 @@ void UpdateGunLoading(unsigned char group)
 
 
         if(chargingInfo[group]->PresentChargingVoltage >= (PSU_MIN_VOL / 10))
         if(chargingInfo[group]->PresentChargingVoltage >= (PSU_MIN_VOL / 10))
         {
         {
+            // unit: 1kW
+            float _diffPowerByCurrent = 0, _diffPowerByPower = 0, _presentTargerPower = 0;
+
+            _presentTargerPower = ((((float)ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000);
+
+            // DiffPower_Available
             ShmPsuGrouping->GroupCollection[group].DiffPower_Available = (((float)(chargingInfo[group]->AvailableChargingCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
             ShmPsuGrouping->GroupCollection[group].DiffPower_Available = (((float)(chargingInfo[group]->AvailableChargingCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
-            ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].CapabilityCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
+
+            // DiffPower_Capability
+            _diffPowerByCurrent = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].CapabilityCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
+            _diffPowerByPower = (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].CapabilityPower / 10) - _presentTargerPower;
+            ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = _diffPowerByPower < _diffPowerByCurrent ? _diffPowerByPower : _diffPowerByCurrent;
+
+            // DiffPower_PhysicalLimit
             ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].RemoteMaxPhysicalCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
             ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].RemoteMaxPhysicalCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
+
+            // DiffPower_ConfigLimit
+            _diffPowerByCurrent = (((float)(ShmChargerInfo->OutputLimit.GunLimitCurrent[group] - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
+            _diffPowerByPower = (ShmChargerInfo->OutputLimit.GunLimitPower[group] / 10) - _presentTargerPower;
+            ShmPsuGrouping->GroupCollection[group].DiffPower_ConfigLimit = _diffPowerByPower < _diffPowerByCurrent ? _diffPowerByPower : _diffPowerByCurrent;
         }
         }
         else
         else
         {
         {
             ShmPsuGrouping->GroupCollection[group].DiffPower_Available = 0;
             ShmPsuGrouping->GroupCollection[group].DiffPower_Available = 0;
             ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = 0;
             ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = 0;
             ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = 0;
             ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = 0;
+            ShmPsuGrouping->GroupCollection[group].DiffPower_ConfigLimit = 0;
         }
         }
     }
     }
     else
     else
@@ -3654,8 +3750,10 @@ void CheckReleaseOrExtend(unsigned char master)
 #endif
 #endif
             }
             }
         }
         }
-        else if(ShmPsuGrouping->GroupCollection[master].DiffPower_Capability <= MAX_DIFF_POWER_TO_EXTEND &&
-            ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit >= MIN_DIFF_PHYSICAL_POWER)
+        else if(ShmPsuGrouping->GroupCollection[master].DiffPower_Available < MAX_DIFF_POWER_TO_EXTEND &&
+            ShmPsuGrouping->GroupCollection[master].DiffPower_Capability < MAX_DIFF_POWER_TO_EXTEND &&
+            ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit >= MIN_DIFF_PHYSICAL_POWER &&
+            ShmPsuGrouping->GroupCollection[master].DiffPower_ConfigLimit >= MIN_DIFF_CONFIG_POWER)
         {
         {
             time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
             time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
 
 
@@ -3667,9 +3765,10 @@ void CheckReleaseOrExtend(unsigned char master)
                 {
                 {
                     if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendAvailable)
                     if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendAvailable)
                     {
                     {
-                        LOG_INFO("Gun %d Extend Capability Available, DifPcap: %.1f kW, DifPphy: %.1f",
+                        LOG_INFO("Gun %d Extend Capability Available, DifPcap: %.1f kW, DiffConfig: %.1f kW, DifPphy: %.1f kW",
                             master + 1,
                             master + 1,
                             ShmPsuGrouping->GroupCollection[master].DiffPower_Capability,
                             ShmPsuGrouping->GroupCollection[master].DiffPower_Capability,
+                            ShmPsuGrouping->GroupCollection[master].DiffPower_ConfigLimit,
                             ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit);
                             ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit);
                         GetClockTime(&_ExtendCapability_time[master]);
                         GetClockTime(&_ExtendCapability_time[master]);
                     }
                     }
@@ -4996,6 +5095,11 @@ void TryCleanPsuAlarm(unsigned char group)
 
 
 void CheckPsuAlarmStatus(void)
 void CheckPsuAlarmStatus(void)
 {
 {
+    if(_isTriggerShutdown)
+    {
+        return;
+    }
+
     for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
     for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
     {
     {
         for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
         for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
@@ -5045,21 +5149,96 @@ void CheckPsuAlarmStatus(void)
     }
     }
 }
 }
 
 
-void ShowPsuErrRecord(int psu_index)
+void ShowInfyPsuErrState(int psu_index)
+{
+    LOG_INFO("Group[%d][%d] Psu[%2d] State2: [%02X], State1: [%02X], State0: [%02X]",
+        ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
+        ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
+        psu_index,
+        ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2],
+        ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1],
+        ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0]);
+}
+
+void InfyPwrStateSummary(void)
+{
+    InfyPsuStateFlagInfo _InfyPwrState;
+
+    memset(&_InfyPwrState, 0x00, sizeof(_InfyPwrState));
+
+    for(int i = 0; i < MAX_PSU_MODULE_QUANTITY; i++)
+    {
+        _InfyPwrState.StateVal[0] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[0];
+        _InfyPwrState.StateVal[1] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[1];
+        _InfyPwrState.StateVal[1] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[2];
+    }
+
+    // 012264
+    // DCDC short circuit
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = _InfyPwrState.bits.OutputShort ? YES : NO;
+
+    // 012334
+    // PSU Failure Alarm
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFault = _InfyPwrState.bits.PsuFault ? YES : NO;
+
+    // 012268
+    // PSU Protection Alarm
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = _InfyPwrState.bits.PsuProtect ? YES : NO;
+
+    // 012269
+    // Fan faults
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = _InfyPwrState.bits.FanFault ? YES : NO;
+
+    // 012226
+    // DCDC over temperature
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = _InfyPwrState.bits.OverTemperature ? YES : NO;
+
+    // 012319
+    // DCDC output over voltage
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = _InfyPwrState.bits.OutputOverVoltage ? YES : NO;
+
+    // 012273
+    // Module unders power limiting status
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = _InfyPwrState.bits.PowerLimit ? YES : NO;
+
+    // 012263
+    // ID number repetition
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = _InfyPwrState.bits.PsuIdRepetition ? YES : NO;
+
+    // 012313
+    // Phase loss
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = _InfyPwrState.bits.InputPhaseLost ? YES : NO;
+
+    // 012271
+    // Under voltage of any phase
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = _InfyPwrState.bits.InputUnderVoltage ? YES : NO;
+
+    // 012270
+    // Over voltage of any phase
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = _InfyPwrState.bits.InputOverVoltage ? YES : NO;
+}
+
+void ShowPhPsuErrRecord(int psu_index)
 {
 {
-    if(ShmPsuPosition->SinglePsuError[psu_index].ErrorCount == 0)
+    if(ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount == 0)
     {
     {
-        LOG_INFO("PSU Group[%d] Index[%d] Error Record Clear", ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo, ShmPsuPosition->PsuAddressInfo[psu_index].GIndex);
+        LOG_INFO("Group[%d][%d] Psu[%2d] Error Record Clear",
+            ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
+            ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
+            psu_index);
     }
     }
     else
     else
     {
     {
         char strErrRecord[128];
         char strErrRecord[128];
         char strError[16];
         char strError[16];
-        sprintf(strErrRecord, "PSU Group[%d] Index[%d] Err:", ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo, ShmPsuPosition->PsuAddressInfo[psu_index].GIndex);
+        sprintf(strErrRecord, "Group[%d][%d] Psu[%2d] Err:",
+            ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
+            ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
+            psu_index);
 
 
-        for(int i = 0; i < ShmPsuPosition->SinglePsuError[psu_index].ErrorCount; i++)
+        for(int i = 0; i < ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount; i++)
         {
         {
-            sprintf(strError, " E-%2d", ShmPsuPosition->SinglePsuError[psu_index].PsuError[i]);
+            sprintf(strError, " E-%2d", ShmPsuPosition->SinglePhPsuError[psu_index].PsuError[i]);
             strcat(strErrRecord, strError);
             strcat(strErrRecord, strError);
         }
         }
         LOG_INFO("%s", strErrRecord);
         LOG_INFO("%s", strErrRecord);
@@ -5068,35 +5247,69 @@ void ShowPsuErrRecord(int psu_index)
 
 
 void CheckPsuErrRecord(void)
 void CheckPsuErrRecord(void)
 {
 {
+    if(_isTriggerShutdown)
+    {
+        return;
+    }
+
     for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
     for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
     {
     {
         for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
         for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
         {
         {
             int psu_index = ShmPsuPosition->GroupLocationInfo[i].PsuIndex[j];
             int psu_index = ShmPsuPosition->GroupLocationInfo[i].PsuIndex[j];
 
 
-            if(ShmPsuPosition->SinglePsuError[psu_index].ErrFlag.bits.Changed)
+            if(ShmChargerInfo->Control.LibCtrl.bits.InfyPwrLib)
             {
             {
-                ShowPsuErrRecord(psu_index);
-                ShmPsuPosition->SinglePsuError[psu_index].ErrFlag.bits.Changed = false;
+                if(ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed)
+                {
+                    ShowInfyPsuErrState(psu_index);
+                    InfyPwrStateSummary();
+                    ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed = false;
+                }
+            }
+
+            if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
+            {
+                if(ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed)
+                {
+                    ShowPhPsuErrRecord(psu_index);
+                    ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed = false;
+                }
             }
             }
         }
         }
     }
     }
 }
 }
 
 
-bool IsPsuGroupAnyAlarmFault(unsigned char group)
+bool IsPsuGroupAnyAlarm(unsigned char group)
+{
+    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_ALARM) > 0)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool IsPsuGroupAnyFault(unsigned char group)
+{
+    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_FAULT) > 0)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool IsPsuGroupAllAlarm(unsigned char group)
 {
 {
-    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_FAULT) ||
-        (ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_ALARM))
+    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_ALARM) > 0)
     {
     {
         return true;
         return true;
     }
     }
     return false;
     return false;
 }
 }
 
 
-bool IsPsuGroupAllAlarmFault(unsigned char group)
+bool IsPsuGroupAllFault(unsigned char group)
 {
 {
-    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_FAULT) ||
-        (ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_ALARM))
+    if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_FAULT) > 0)
     {
     {
         return true;
         return true;
     }
     }
@@ -5145,6 +5358,7 @@ void PsuGroupControlProcess(void)
                     ShmPsuGrouping->TotalGroupOutput[group].GTargetVoltage = 0;
                     ShmPsuGrouping->TotalGroupOutput[group].GTargetVoltage = 0;
                     ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent = 0;
                     ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent = 0;
                     SetPsuGroupOutput(group);
                     SetPsuGroupOutput(group);
+                    UpdatePsuGroupLoading(group);
                 }
                 }
 
 
                 if(isStartOutputSwitch[group])
                 if(isStartOutputSwitch[group])
@@ -5152,33 +5366,44 @@ void PsuGroupControlProcess(void)
                     SetPsuGroupPowerOnOff(group, _PSU_OFF);
                     SetPsuGroupPowerOnOff(group, _PSU_OFF);
                 }
                 }
 
 
-                if(IsPsuGroupAnyAlarmFault(group))
+                if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
                 {
                 {
-                    time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
-
-                    if(time >= PSU_CLEAN_ERR_INTERVAL)
+                    if(IsPsuGroupAnyAlarm(group))
                     {
                     {
-                        PSU_LOG("PSU Group[%d] Alarm or Fault Occur, Need Do Something", group);
-                        GetClockTime(&_CleanPsuAlarm_time[group]);
-                    }
-                }
-                else if(IsPsuGroupAnyLock(group))
-                {
-                    time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
+                        time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
 
 
-                    if(time >= PSU_CLEAN_ERR_INTERVAL)
+                        if(time >= PSU_CLEAN_ERR_INTERVAL)
+                        {
+                            PSU_LOG("PSU Group[%d] Alarm or Fault Occur, Need Do Something", group);
+                            GetClockTime(&_CleanPsuAlarm_time[group]);
+                        }
+                        // if module exist any alarm or fault, break here
+                        break;
+                    }
+                    else if(IsPsuGroupAnyLock(group))
                     {
                     {
-                        TryCleanPsuAlarm(group);
-                        GetClockTime(&_CleanPsuAlarm_time[group]);
+                        time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
+
+                        if(time >= PSU_CLEAN_ERR_INTERVAL)
+                        {
+                            TryCleanPsuAlarm(group);
+                            GetClockTime(&_CleanPsuAlarm_time[group]);
+                        }
+                        // if module exist any lock, break here
+                        break;
                     }
                     }
                 }
                 }
-                else
+
+                if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue != 0)
                 {
                 {
-                    if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue != 0 &&
-                        ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
+                    if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
                     {
                     {
                         CheckChargingRequest(group);
                         CheckChargingRequest(group);
                     }
                     }
+                    else
+                    {
+
+                    }
                 }
                 }
                 break;
                 break;
 
 
@@ -5224,17 +5449,19 @@ void PsuGroupControlProcess(void)
                     }
                     }
                     ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest = true;
                     ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest = true;
                 }
                 }
-                if(IsPsuGroupAllAlarmFault(group))
+                if((IsPsuGroupAllAlarm(group) || IsPsuGroupAllFault(group)) &&
+                    !_isTriggerShutdown &&
+                    !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest)
                 {
                 {
-                    if(!ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupAllAlarmFault)
+                    if(!ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupNoResource)
                     {
                     {
-                        LOG_INFO("Gun %d PsuGroup All Alarm/Fault, Need Stop Charging", group + 1);
+                        LOG_INFO("Gun %d PsuGroup All Alarm/Fault >> No Resource, Need Stop Charging", group + 1);
                     }
                     }
                     if(strncmp(ShmChargerInfo->GunError[group].GunAlarmCode, "", 6) == EQUAL)
                     if(strncmp(ShmChargerInfo->GunError[group].GunAlarmCode, "", 6) == EQUAL)
                     {
                     {
-                        strcpy(ShmChargerInfo->GunError[group].GunAlarmCode, "042268");
+                        strcpy(ShmChargerInfo->GunError[group].GunAlarmCode, "042279");
                     }
                     }
-                    ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupAllAlarmFault = true;
+                    ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupNoResource = true;
                 }
                 }
 
 
                 if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue == 0)
                 if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue == 0)
@@ -5323,7 +5550,7 @@ void PsuGroupControlProcess(void)
                 }
                 }
                 else
                 else
                 {
                 {
-                    if(IsPsuGroupAllAlarmFault(group))
+                    if(IsPsuGroupAllAlarm(group) || IsPsuGroupAllFault(group))
                     {
                     {
                         if(!ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.SlavePowerOffRequest)
                         if(!ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.SlavePowerOffRequest)
                         {
                         {
@@ -5673,7 +5900,7 @@ void PsuGroupAvailableSimulation(void)
 
 
             if((master - 1) != i)
             if((master - 1) != i)
             {
             {
-                chargingInfo[i]->AvailableChargingCurrent = 0;;
+                chargingInfo[i]->AvailableChargingCurrent = 0;
                 chargingInfo[i]->AvailableChargingPower = 0;
                 chargingInfo[i]->AvailableChargingPower = 0;
                 chargingInfo[i]->RealRatingPower = 0;
                 chargingInfo[i]->RealRatingPower = 0;
                 chargingInfo[i]->MaximumChargingVoltage = 0;
                 chargingInfo[i]->MaximumChargingVoltage = 0;
@@ -5908,6 +6135,42 @@ bool IsShutdownCompleted(void)
     return done;
     return done;
 }
 }
 
 
+void PsuIndication(void)
+{
+    if(ShmChargerInfo->Control.LibCtrl.bits.InfyPwrLib)
+    {
+        for(int i = 0; i < MAX_PSU_MODULE_QUANTITY; i++)
+        {
+            if(ShmPsuPosition->SingleInfyPwrState[i].InfyPwrStateFlag.bits.Indicated)
+            {
+                LedSingleOnOff(i, _PSU_ON);
+                LOG_INFO("Set Psu[%2d] Led Blinking", i);
+                _Psu_Indication_Enable[i] = true;
+                _Psu_Indication_Count[i] = PSU_INDICATION_TIME;
+                ShmPsuPosition->SingleInfyPwrState[i].InfyPwrStateFlag.bits.Indicated = false;
+            }
+            else
+            {
+                if(_Psu_Indication_Enable[i])
+                {
+                    _Psu_Indication_Count[i]--;
+
+                    if(_Psu_Indication_Count[i] == 0)
+                    {
+                        LedSingleOnOff(i, _PSU_OFF);
+                        LOG_INFO("Set Psu[%2d] Led Static", i);
+                        _Psu_Indication_Enable[i] = false;
+                    }
+                }
+            }
+        }
+    }
+    if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
+    {
+
+    }
+}
+
 int main(void)
 int main(void)
 {
 {
     byte _TotalModuleCount = 0;
     byte _TotalModuleCount = 0;
@@ -6377,13 +6640,15 @@ int main(void)
 				            GetModuleCount(i);
 				            GetModuleCount(i);
 				            GetModuleInputVol(i);
 				            GetModuleInputVol(i);
 
 
-                            if(IsPsuGroupAnyAlarmFault(i))
+                            if(IsPsuGroupAnyAlarm(i) || IsPsuGroupAnyFault(i))
                             {
                             {
                                 GetErrorRecord(i);
                                 GetErrorRecord(i);
                             }
                             }
 				        }
 				        }
 				    }
 				    }
 
 
+				    PsuIndication();
+
                     for(int i = 0; i < MAX_GUN_QUANTITY; i++)
                     for(int i = 0; i < MAX_GUN_QUANTITY; i++)
                     {
                     {
                         UpdateGunTotalPsuQuantity(i);
                         UpdateGunTotalPsuQuantity(i);

+ 514 - 70
EVSE/Projects/DO360/Apps/ReadCmdline.c

@@ -44,17 +44,19 @@
 typedef unsigned char			byte;
 typedef unsigned char			byte;
 #define	NO_DEFINE			    255
 #define	NO_DEFINE			    255
 
 
-#define OPTION_CNT              3
+#define OPTION_CNT              4
 #define STR_OPTION              '-'
 #define STR_OPTION              '-'
 #define OPTION_REFLASH          0x00000001
 #define OPTION_REFLASH          0x00000001
 #define OPTION_LOOP             0x00000002
 #define OPTION_LOOP             0x00000002
-#define OPTION_TIME             0x00000004
+#define OPTION_OUTPUT_FILE      0x00000004
+#define OPTION_TIME             0x00000008
 
 
 #define MAX_SUB_CMD_QUANTITY    16
 #define MAX_SUB_CMD_QUANTITY    16
 #define MAX_SUB_CMD_LENGTH      128
 #define MAX_SUB_CMD_LENGTH      128
 
 
 #define STR_OPT_REFLASH         'f'
 #define STR_OPT_REFLASH         'f'
 #define STR_OPT_LOOP            'l'
 #define STR_OPT_LOOP            'l'
+#define STR_OPT_OUTPUT_FILE     'o'
 #define STR_OPT_TIME            't'
 #define STR_OPT_TIME            't'
 
 
 #define TTY_PATH                "/dev/tty"
 #define TTY_PATH                "/dev/tty"
@@ -356,8 +358,8 @@ int ParsingCmd(char *inputString, char *outputString)
 bool IsOption(char *strCmd, unsigned int *opt)
 bool IsOption(char *strCmd, unsigned int *opt)
 {
 {
     int len = 0;
     int len = 0;
-    char str_opt[OPTION_CNT] = {STR_OPT_REFLASH, STR_OPT_LOOP, STR_OPT_TIME};
-    unsigned int opt_value[OPTION_CNT] = {OPTION_REFLASH, OPTION_LOOP, OPTION_TIME};
+    char str_opt[OPTION_CNT] = {STR_OPT_REFLASH, STR_OPT_LOOP, STR_OPT_OUTPUT_FILE, STR_OPT_TIME};
+    unsigned int opt_value[OPTION_CNT] = {OPTION_REFLASH, OPTION_LOOP, OPTION_OUTPUT_FILE, OPTION_TIME};
 
 
     len = strlen(strCmd);
     len = strlen(strCmd);
 
 
@@ -1947,47 +1949,181 @@ void SetTestControl(char *v1, char *v2)
     printf("\r\n");
     printf("\r\n");
 }
 }
 
 
-// Gun  Role  Master  K1K2  GTVoltage  GTCurrent  StableCurrent  OutputLoading  GunLoading  DiffP_Ava  DiffP_Cap  DiffP_Lim
-//  1    00     00      0     0000 V    000.0 A       0000 A         XXX.XX       XXX.XX      XXX kw     XXX kW    XXX kW
-void ShowGroupingDemand(void)
+//                                                        Group     Gun                                    Available               Psu Group Control
+// Gun  Role  Master  K1K2   GTVol     GTCur  StableCur  Loading  Loading  DiffP_Ava  DiffP_Cap  DiffP_Lim  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      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
+void ShowGroupingDemand(char *inputCmd, unsigned int opt)
 {
 {
-    byte target = 0;
-    unsigned char k1k2 = 0;
+    bool keepRun = false;
+    bool reflash = false;
+    bool outputFile = false;
+    bool allRoleIdle = false;
+    bool fullInfo = false;
+    int totalCnt = 0;
 
 
-    printf("\r\n Gun  Role  Master  K1K2  GTVoltage  GTCurrent  StableCurrent  OutputLoading  GunLoading  DiffP_Ava  DiffP_Cap  DiffP_Lim");
+    totalCnt = GetSubCommand(inputCmd);
 
 
-    for(int i = 0; i < 4; i++)
+    if(totalCnt == 1)
     {
     {
-        target = ShmPsuGrouping->Layout[i];
-        if(ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup != 0)
+        if(strcmp(&MultiSubCmd[0][0], "full") == 0)
         {
         {
-            k1k2 = _chargingData[ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup - 1]->RelayK1K2Status;
+            fullInfo = true;
         }
         }
-        else
+    }
+
+    int time = 0;
+    struct timespec _Loop_time;
+    char lineString[512];
+    char tempString[128];
+
+    if((opt & OPTION_REFLASH) || (opt & OPTION_LOOP) > 0)
+    {
+        keepRun = true;
+    }
+
+    if((opt & OPTION_OUTPUT_FILE) > 0)
+    {
+        outputFile = true;
+    }
+
+    byte target = 0;
+    unsigned char k1k2 = 0;
+
+    //printf("                                                        Group     Gun                                    Available               Psu Group Control\r\n");
+    //printf(" Gun  Role  Master  K1K2   GTVol     GTCur  StableCur  Loading  Loading  DiffP_Ava  DiffP_Cap  DiffP_Lim  Partner  IdleCtrl Master   Stop  Derating  Extend   Slave\r\n");
+    memset(lineString, 0x00, sizeof(lineString));
+    sprintf(lineString, "                                                        Group     Gun                                       DiffP");
+    if(fullInfo)
+    {
+        sprintf(tempString, "   Available               Psu Group Control");
+        strcat(lineString, tempString);
+    }
+    if(!outputFile)
+    {
+        printf("%s\r\n", lineString);
+    }
+    else
+    {
+        ReadCmd_INFO("%s", lineString);
+    }
+
+    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");
+        strcat(lineString, tempString);
+    }
+    if(!outputFile)
+    {
+        printf("%s\r\n", lineString);
+    }
+    else
+    {
+        ReadCmd_INFO("%s", lineString);
+    }
+
+    do
+    {
+        time = GetTimeoutValue(_Loop_time) / mSEC_VAL;
+        if(time >= 1000)
         {
         {
-            k1k2 = _chargingData[target]->RelayK1K2Status;
+            if(reflash)
+            {
+                ConsoleReflash(MAX_GROUP_QUANTITY, 1);
+            }
+
+            for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
+            {
+                target = ShmPsuGrouping->Layout[i];
+                if(ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup != 0)
+                {
+                    k1k2 = _chargingData[ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup - 1]->RelayK1K2Status;
+                }
+                else
+                {
+                    k1k2 = _chargingData[target]->RelayK1K2Status;
+                }
+
+                memset(lineString, 0x00, sizeof(lineString));
+                sprintf(tempString, "  %d    %2d     %02X      %d   %4d V   %3d.%d A    %4d A    %3d.%02d",
+                    target + 1, ShmChargerInfo->PsuGrouping.GroupCollection[target].Role, ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup, k1k2,
+                    (ShmPsuGrouping->GroupOutput[target].GTargetVoltage / 10),
+                    (ShmPsuGrouping->GroupOutput[target].GTargetCurrent / 10),
+                    (ShmPsuGrouping->GroupOutput[target].GTargetCurrent % 10),
+                    (int)(_chargingData[target]->AvailableChargingCurrent / 10),
+                    (ShmPsuGrouping->GroupOutput[target].OutputLoading / 100),
+                    (ShmPsuGrouping->GroupOutput[target].OutputLoading % 100));
+                strcat(lineString, tempString);
+
+                //if(ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup == target + 1)
+                //{
+                    sprintf(tempString, "   %3d.%02d", (ShmChargerInfo->PsuGrouping.GroupCollection[target].GunLoading / 100), (ShmChargerInfo->PsuGrouping.GroupCollection[target].GunLoading % 100));
+                    strcat(lineString, tempString);
+
+
+                    sprintf(tempString, "    %3d kW     %3d kW    %3d kW      %3d kW",
+                        (int)ShmPsuGrouping->GroupCollection[target].DiffPower_Available,
+                        (int)ShmPsuGrouping->GroupCollection[target].DiffPower_Capability,
+                        (int)ShmPsuGrouping->GroupCollection[target].DiffPower_PhysicalLimit,
+                        (int)ShmPsuGrouping->GroupCollection[target].DiffPower_ConfigLimit);
+                    strcat(lineString, tempString);
+
+                    if(fullInfo)
+                    {
+                        int partner_quantity = GetPsuGroupAvailable(target);
+                        sprintf(tempString, "     %2d      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);
+                        strcat(lineString, tempString);
+                    }
+                //}
+
+                if(!outputFile)
+                {
+                    printf("%s\r\n", lineString);
+                }
+                else
+                {
+                    if(!allRoleIdle)
+                    {
+                        ReadCmd_INFO("%s", lineString);
+                    }
+                }
+            }
+
+            allRoleIdle = true;
+            for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
+            {
+                if(ShmChargerInfo->PsuGrouping.GroupCollection[i].Role != _GROLE_IDLE)
+                {
+                    allRoleIdle = false;
+                }
+            }
+
+            GetClockTime(&_Loop_time);
+            if((opt & OPTION_REFLASH) > 0 && !outputFile)
+            {
+                reflash = true;
+            }
         }
         }
 
 
-        printf("\r\n  %d    %2d     %02X      %d     %4d V    %3d.%d A       %4d A         %3d.%02d",
-            target + 1, ShmChargerInfo->PsuGrouping.GroupCollection[target].Role, ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup, k1k2,
-            (ShmPsuGrouping->GroupOutput[target].GTargetVoltage / 10),
-            (ShmPsuGrouping->GroupOutput[target].GTargetCurrent / 10),
-            (ShmPsuGrouping->GroupOutput[target].GTargetCurrent % 10),
-            (int)(_chargingData[target]->AvailableChargingCurrent / 10),
-            (ShmPsuGrouping->GroupOutput[target].OutputLoading / 100),
-            (ShmPsuGrouping->GroupOutput[target].OutputLoading % 100));
-        if(ShmChargerInfo->PsuGrouping.GroupCollection[target].TargetGroup == target + 1)
+        if(keepRun)
         {
         {
-            printf("       %3d.%02d", (ShmChargerInfo->PsuGrouping.GroupCollection[target].GunLoading / 100), (ShmChargerInfo->PsuGrouping.GroupCollection[target].GunLoading % 100));
-
-            printf("      %3d kW     %3d kW    %3d kW",
-                (int)ShmPsuGrouping->GroupCollection[target].DiffPower_Available,
-                (int)ShmPsuGrouping->GroupCollection[target].DiffPower_Capability,
-                (int)ShmPsuGrouping->GroupCollection[target].DiffPower_PhysicalLimit);
+            keepRun = IsLoopStopCmd() ? false : true;
+            usleep(10000);
         }
         }
-    }
+    }while(keepRun);
 
 
-    printf("\r\n\r\n");
+    printf("\r\n");
 }
 }
 
 
 // v1: gun
 // v1: gun
@@ -3673,7 +3809,15 @@ void EvCommMsgDebug(char *inputCmd, unsigned int opt)
 
 
     bool find = false;
     bool find = false;
     int reg = 0, enable = 0;
     int reg = 0, enable = 0;
-    reg = atoi(&MultiSubCmd[0][0]);
+
+    if(strcmp(&MultiSubCmd[0][0], "0x") == EQUAL && strlen(&MultiSubCmd[0][0]) > 2)
+    {
+        reg = (int)strtol(&MultiSubCmd[0][0], NULL, 16);
+    }
+    else
+    {
+        reg = atoi(&MultiSubCmd[0][0]);
+    }
     enable = atoi(&MultiSubCmd[1][0]);
     enable = atoi(&MultiSubCmd[1][0]);
 
 
     if(enable > 1 || enable < 0)
     if(enable > 1 || enable < 0)
@@ -4785,7 +4929,7 @@ void RelayCmd(char *inputCmd, unsigned int opt)
     memset(subMain, 0x00, sizeof(subMain));
     memset(subMain, 0x00, sizeof(subMain));
     memset(subSub, 0x00, sizeof(subSub));
     memset(subSub, 0x00, sizeof(subSub));
 
 
-    if(MainAndSubCommandParsing(inputCmd, subMain, subSub) >= 2)
+    if(MainAndSubCommandParsing(inputCmd, subMain, subSub) == 2)
     {
     {
         if(strcmp(subMain, "abnormal") == EQUAL)
         if(strcmp(subMain, "abnormal") == EQUAL)
         {
         {
@@ -5236,6 +5380,194 @@ void ShowOccupancy(char *inputCmd, unsigned int opt)
     printf("\r\n");
     printf("\r\n");
 }
 }
 
 
+void SetCustomizedFlag(int shift, bool enable)
+{
+    if(enable)
+    {
+        ShmChargerInfo->Control.CustomizedInfo.Flag.CtrlValue |= (1 << shift);
+    }
+    else
+    {
+        ShmChargerInfo->Control.CustomizedInfo.Flag.CtrlValue &= ~(1 << shift);
+    }
+}
+
+// super customized standby [enable/disable]
+// super customized tccstandby [enable/disable]
+// super customized standbyfast [enable/disable]
+// super customized freestandby [enable/disable]
+// super customized tilt [enable/disable]
+void SetCustomizedCmd(char *inputCmd)
+{
+    int totalCnt = 0, maxPara = 0;
+
+    maxPara = 2;
+    totalCnt = GetSubCommand(inputCmd);
+
+    if(totalCnt != maxPara)
+    {
+        printf("Input cmd fail ------  super [customized] [disstandby | tccstandby | standbyfast | cstandby | tilt] [enable | disable]\r\n\r\n");
+        return;
+    }
+
+    int maxCustomized = 5;
+    int shift = 0;
+    bool enable = false, find = false;;
+
+    enable = strcmp(&MultiSubCmd[1][0], "enable") == EQUAL ? true : false;
+
+
+    char *str_customized[] = {"disstandby", "tccstandby", "standbyfast", "freestandby", "tilt"};
+
+    for(int i = 0; i < maxCustomized; i++)
+    {
+        if(strcmp(&MultiSubCmd[0][0], str_customized[i]) == EQUAL)
+        {
+            shift = i;
+            find = true;
+            break;
+        }
+    }
+
+    if(find)
+    {
+        SetCustomizedFlag(shift, enable);
+        printf("\r\n");
+        printf("%s %s customized flag\r\n\r\n", enable ? "Enable" : "Disable", str_customized[shift]);
+
+        return;
+    }
+
+    printf("\r\n");
+    printf("Input cmd fail ------  super [customized] [disstandby | tccstandby | standbyfast | cstandby | tilt] [enable | disable]\r\n\r\n");
+}
+
+void TiltSensorTrigger(void)
+{
+    ShmChargerInfo->Control.CustomizedInfo.TiltSensorStep = _TILT_SENSOR_NONE;
+    printf("\r\n");
+    printf("Reset tilt sensor step\r\n\r\n");
+}
+
+void TiltSensorCmd(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)
+    {
+        if(strcmp(subMain, "test") == 0)
+        {
+            TiltSensorTrigger();
+            return;
+        }
+    }
+    printf("\r\n");
+    printf("Input cmd fail ------  super [tilt] [test]\r\n\r\n");
+}
+
+void SetStandbyTime(int time)
+{
+    if(time != 0)
+    {
+        ShmChargerInfo->Control.CustomizedInfo.StandbyTime = time;
+        printf("\r\n");
+        printf("Set standby time [%d] (s)\r\n\r\n", ShmChargerInfo->Control.CustomizedInfo.StandbyTime);
+    }
+    else
+    {
+        printf("\r\n");
+        printf("Unavailable value, standby time [%d] (s)\r\n\r\n", ShmChargerInfo->Control.CustomizedInfo.StandbyTime);
+    }
+}
+
+void StandbyTimeCmd(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)
+    {
+        int _time = atoi(subMain);
+
+        SetStandbyTime(_time);
+        return;
+    }
+    printf("\r\n");
+    printf("Input cmd fail ------  super [standby] [value(seconds)]\r\n\r\n");
+}
+
+void DiagnosticsEnable(void)
+{
+    ShmChargerInfo->Control.Diagnostics.DiagnosticsType = DIAGNOSTICS_TYPE_ALL;
+    printf("\r\n");
+    printf("Dispenser Diagnostics Enable\r\n\r\n");
+}
+
+void DiagnosticsCmd(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)
+    {
+        if(strcmp(subMain, "enable") == 0)
+        {
+            DiagnosticsEnable();
+            return;
+        }
+    }
+    printf("\r\n");
+    printf("Input cmd fail ------  super [diagnostics] [enable]\r\n\r\n");
+}
+
+void SuperMode(char *inputCmd, unsigned int opt)
+{
+    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)
+    {
+        if(strcmp(subMain, "customized") == 0)
+        {
+            SetCustomizedCmd(subSub);
+            return;
+        }
+
+        if(strcmp(subMain, "tilt") == 0)
+        {
+            TiltSensorCmd(subSub);
+            return;
+        }
+
+        if(strcmp(subMain, "standby") == 0)
+        {
+            StandbyTimeCmd(subSub);
+            return;
+        }
+
+        if(strcmp(subMain, "diagnostics") == 0)
+        {
+            DiagnosticsCmd(subSub);
+            return;
+        }
+    }
+    printf("\r\n");
+    printf("Input cmd fail ------  super [customized | tilt | standby | diagnostics] [...]\r\n\r\n");
+}
+
 int ShowPsuCount(void)
 int ShowPsuCount(void)
 {
 {
     int line = 0;
     int line = 0;
@@ -5322,18 +5654,22 @@ 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   %4d A  %4d kW",
+        printf("  G-%d    %2d  %4d.%d V  %4d.%d A  %4d kW",
             group + 1,
             group + 1,
             ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity,
             ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity,
             (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent / 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent / 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent % 10),
             (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent % 10),
-            (ShmPsuData->PsuGroup[group].GroupPresentOutputPower / 10),
+            (ShmPsuData->PsuGroup[group].GroupPresentOutputPower / 10));
+
+        printf("   %4d V   %4d A   %4d A  %4d kW",
+            (ShmPsuGrouping->GroupOutput[group].GTargetVoltage / 10),
+            (ShmPsuGrouping->GroupOutput[group].GTargetCurrent / 10),
             (ShmPsuData->PsuGroup[group].GroupAvailableCurrent / 10),
             (ShmPsuData->PsuGroup[group].GroupAvailableCurrent / 10),
             (ShmPsuData->PsuGroup[group].GroupAvailablePower / 10));
             (ShmPsuData->PsuGroup[group].GroupAvailablePower / 10));
 
 
-        printf("                                                   |   %d%d%d%d  |   %d%d%d%d\r\n",
+        printf("                               |   %d%d%d%d  |   %d%d%d%d\r\n",
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Lock,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Lock,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Alarm,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Alarm,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Fault,
             ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].bits.Fault,
@@ -5358,7 +5694,7 @@ int ShowSinglePsuInfo(int psu_index)
     group = ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo;
     group = ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo;
     gIndex = ShmPsuPosition->PsuAddressInfo[psu_index].GIndex;
     gIndex = ShmPsuPosition->PsuAddressInfo[psu_index].GIndex;
 
 
-    printf("  %2d     %2d  %4d.%d V  %4d.%d A  %4d kW   %4d A  %4d kW",
+    printf("  %2d     %2d  %4d.%d V  %4d.%d A  %4d kW                     %4d A  %4d kW",
         gIndex + 1,
         gIndex + 1,
         psu_index,
         psu_index,
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].PresentOutputVoltage / 10),
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].PresentOutputVoltage / 10),
@@ -5369,42 +5705,40 @@ int ShowSinglePsuInfo(int psu_index)
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].IAvailableCurrent / 10),
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].IAvailableCurrent / 10),
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailablePower / 10));
         (ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailablePower / 10));
 
 
-    int CriticalTemp1 = 0, CriticalTemp2 = 0, CriticalTemp3 = 0, InletTemp = 0, OutletTemp = 0, InletTemp_1 = 0, InletTemp_2 = 0;
-    CriticalTemp1 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp1 - 60;
-    CriticalTemp2 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp2 - 60;
-    CriticalTemp3 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp3 - 60;
-    InletTemp = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp - 60;
-    OutletTemp = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].OutletTemp - 60;
-    InletTemp_1 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_1 - 60;
-    InletTemp_2 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_2 - 60;
-
-    printf("   %4d    %4d / %4d  %4d / %4d   %4d / %4d",
-        CriticalTemp1, InletTemp, OutletTemp, InletTemp_1, InletTemp_2, CriticalTemp2, CriticalTemp3);
+    printf("   %3d.%d V   %3d.%d V   %3d.%d V",
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL1 / 10),
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL1 % 10),
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL2 / 10),
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL2 % 10),
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL3 / 10),
+        (ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL3 % 10));
 
 
-    printf("  |   %d%d%d%d\r\n",
+    printf(" |   %d%d%d%d",
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Lock,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Lock,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Alarm,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Alarm,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Fault,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Fault,
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Output);
         ShmPsuPosition->SinglePsuStatus[psu_index].bits.Output);
 
 
+    printf("\r\n");
+
     return 1;
     return 1;
 }
 }
 
 
-// Group  Psu   Out_Vol   Out_Cur  Out_Pow  Ava_Cur  Ava_Pow  Ambient   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2   OR_LAFO  AND_LAFO
-//  G-X     4  XXXX.X V  XXXX.X A  XXXX kW   XXXX A  XXXX kW                                                   |   XXXX  |   XXXX
+// Group  Psu   Out_Vol   Out_Cur  Out_Pow  TargetV  TargetC  Ava_Cur  Ava_Pow  Ambient   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2   OR_LAFO  AND_LAFO  InVol L1  InVol L2  InVol L3
+//  G-X     4  XXXX.X V  XXXX.X A  XXXX kW   XXXX V   XXXX A   XXXX A  XXXX kW                                                   |   XXXX  |   XXXX
 //  G-X     0     N/A        N/A      N/A      N/A      N/A
 //  G-X     0     N/A        N/A      N/A      N/A      N/A
-//   X      0  XXXX.X V  XXXX.X A  XXXX kW   XXXX A  XXXX kW   XXXX    XXXX / XXXX  XXXX / XXXX   XXXX / XXXX  |   XXXX  |   XXXX
+//   X      0  XXXX.X V  XXXX.X A  XXXX kW   XXXX A  XXXX kW   XXXX    XXXX / XXXX  XXXX / XXXX   XXXX / XXXX  |   XXXX  |   XXXX   XXX.X V   XXX.X V   XXX.X V
 
 
-// Group  Out_Vol   Out_Cur  Out_Pow  Ava_Cur  Ava_Pow     Version  Ambient   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2   OR_LAFO  AND_LAFO
-//  G-X  XXXX.X V  XXXX.X A  XXXX kW   XXXX A  XXXX kW,  Total: XX                                                   |   XXXX  |   XXXX
-//  G-X    N/A        N/A      N/A      N/A      N/A
-//   X   XXXX.X V  XXXX.X A  XXXX kW   XXXX A  XXXX kW  XXXXXXXXXX   XXXX    XXXX / XXXX  XXXX / XXXX   XXXX / XXXX  |   XXXX  |   XXXX
+// Group  Psu   Out_Vol   Out_Cur  Out_Pow  TargetV  TargetC  Ava_Cur  Ava_Pow  InVol L1  InVol L2  InVol L3  OR_LAFO  AND_LAFO
+//  G-X     4  XXXX.X V  XXXX.X A  XXXX kW   XXXX V   XXXX A   XXXX A  XXXX kW                               |   XXXX  |   XXXX
+//  G-X     0     N/A        N/A      N/A      N/A      N/A      N/A      N/A
+//   X      0  XXXX.X V  XXXX.X A  XXXX kW                     XXXX A  XXXX kW   XXX.X V   XXX.X V   XXX.X V |   XXXX  |   XXXX
 int ShowPsuInfo(void)
 int ShowPsuInfo(void)
 {
 {
-    int line = 2;
-    printf("                                                                      PFC  &  DD\r\n");
-    printf(" Group  Psu   Out_Vol   Out_Cur  Out_Pow  Ava_Cur  Ava_Pow  Ambient   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2   OR_LAFO  AND_LAFO\r\n");
+    int line = 1;
 
 
+    //printf(" Group  Psu   Out_Vol   Out_Cur  Out_Pow  Ava_Cur  Ava_Pow  InVol L1  InVol L2  InVol L3  OR_LAFO  AND_LAFO\r\n");
+    printf(" Group  Psu   Out_Vol   Out_Cur  Out_Pow  TargetV  TargetC  Ava_Cur  Ava_Pow  InVol L1  InVol L2  InVol L3  OR_LAFO  AND_LAFO\r\n");
     for(int i = 0; i < CONNECTOR_QUANTITY; i++)
     for(int i = 0; i < CONNECTOR_QUANTITY; i++)
     {
     {
         line += ShowPsuGroupInfo(i);
         line += ShowPsuGroupInfo(i);
@@ -5420,6 +5754,70 @@ int ShowPsuInfo(void)
     return line;
     return line;
 }
 }
 
 
+int ShowSinglePsuTemperature(int psu_index)
+{
+    int group = 0, gIndex = 0;
+
+    group = ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo;
+    gIndex = ShmPsuPosition->PsuAddressInfo[psu_index].GIndex;
+
+    int CriticalTemp1 = 0, CriticalTemp2 = 0, CriticalTemp3 = 0, InletTemp = 0, OutletTemp = 0, InletTemp_1 = 0, InletTemp_2 = 0;
+    CriticalTemp1 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp1 - 60;
+    CriticalTemp2 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp2 - 60;
+    CriticalTemp3 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp3 - 60;
+    InletTemp = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp - 60;
+    OutletTemp = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].OutletTemp - 60;
+    InletTemp_1 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_1 - 60;
+    InletTemp_2 = (int)ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_2 - 60;
+
+    printf("   %d    %2d   %4d  %4d / %4d  %4d / %4d   %4d / %4d\r\n",
+        group, psu_index, CriticalTemp1, InletTemp, OutletTemp, InletTemp_1, InletTemp_2, CriticalTemp2, CriticalTemp3);
+
+    return 1;
+}
+
+//              PFC  &  DD
+// Group Psu   Ambi   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2
+//   X    XX   XXXX  XXXX / XXXX  XXXX / XXXX   XXXX / XXXX
+int ShowPsuTemperature(void)
+{
+    int line = 2;
+    printf("                    PFC  &  DD\r\n");
+    printf(" Group Psu   Ambi   Liq_In_Out  DD_In 1 & 2  DD_Out 1 & 2\r\n");
+    for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
+    {
+        if(ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity > 0)
+        {
+            for(int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
+            {
+                int psu_index = ShmPsuPosition->GroupLocationInfo[i].PsuIndex[j];
+                line += ShowSinglePsuTemperature(psu_index);
+            }
+        }
+    }
+
+    return line;
+}
+
+void SetPsuIndication(int psuIndex)
+{
+    if(psuIndex >= MAX_PSU_MODULE_QUANTITY)
+    {
+        printf("psu index(%d) over range(%d)\r\n", psuIndex, MAX_PSU_MODULE_QUANTITY);
+        return;
+    }
+
+    if(ShmChargerInfo->Control.LibCtrl.bits.InfyPwrLib)
+    {
+        ShmPsuPosition->SingleInfyPwrState[psuIndex].InfyPwrStateFlag.bits.Indicated = true;
+        printf("Set Psu[%2d] Led Blinking\r\n", psuIndex);
+    }
+    if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
+    {
+        printf("PhPwer not support this function\r\n");
+    }
+}
+
 void PsuCmd(char *inputCmd, unsigned int opt)
 void PsuCmd(char *inputCmd, unsigned int opt)
 {
 {
     bool keepRun = false;
     bool keepRun = false;
@@ -5438,9 +5836,9 @@ void PsuCmd(char *inputCmd, unsigned int opt)
     maxPara = 1;
     maxPara = 1;
     totalCnt = GetSubCommand(inputCmd);
     totalCnt = GetSubCommand(inputCmd);
 
 
-    if(totalCnt != maxPara)
+    if(totalCnt < maxPara)
     {
     {
-        printf("Input cmd fail ------  psu [count | ver | cap | input | output | info]\r\n\r\n");
+        printf("Input cmd fail ------  psu [count | ver | cap | input | output | info | temp | indi]\r\n\r\n");
         return;
         return;
     }
     }
 
 
@@ -5459,6 +5857,10 @@ void PsuCmd(char *inputCmd, unsigned int opt)
             {
             {
                 reflashLine = ShowPsuInfo();
                 reflashLine = ShowPsuInfo();
             }
             }
+            else if(strcmp(&MultiSubCmd[0][0], "temp") == EQUAL)
+            {
+                reflashLine = ShowPsuTemperature();
+            }
             else if(strcmp(&MultiSubCmd[0][0], "count") == EQUAL)
             else if(strcmp(&MultiSubCmd[0][0], "count") == EQUAL)
             {
             {
                 reflashLine = ShowPsuCount();
                 reflashLine = ShowPsuCount();
@@ -5479,9 +5881,24 @@ void PsuCmd(char *inputCmd, unsigned int opt)
             {
             {
                 reflashLine = ShowPsuOutput();
                 reflashLine = ShowPsuOutput();
             }
             }
+            else if(strcmp(&MultiSubCmd[0][0], "indi") == EQUAL)
+            {
+                int psuIndex = 0;
+
+                if(totalCnt == 2)
+                {
+                    psuIndex = atoi(&MultiSubCmd[1][0]);
+                    SetPsuIndication(psuIndex);
+                }
+                else
+                {
+                    printf("Input cmd parsing fail ------  psu [indi] [index]\r\n");
+                }
+                keepRun = false;
+            }
             else
             else
             {
             {
-                printf("Input cmd parsing fail ------  psu [count | ver | cap | input | output | info]\r\n");
+                printf("Input cmd parsing fail ------  psu [count | ver | cap | input | output | info | temp | indi]\r\n");
                 keepRun = false;
                 keepRun = false;
             }
             }
 
 
@@ -5502,7 +5919,7 @@ void PsuCmd(char *inputCmd, unsigned int opt)
     printf("\r\n");
     printf("\r\n");
 }
 }
 
 
-int main(void)
+int main(int argc, char *argv[])
 {
 {
     char newString[32][MAX_SUB_CMD_LENGTH];
     char newString[32][MAX_SUB_CMD_LENGTH];
     char inputString[MAX_SUB_CMD_LENGTH], normalCmd[MAX_SUB_CMD_LENGTH];
     char inputString[MAX_SUB_CMD_LENGTH], normalCmd[MAX_SUB_CMD_LENGTH];
@@ -5537,12 +5954,30 @@ int main(void)
         memset(&newString[i], 0x00, 32);
         memset(&newString[i], 0x00, 32);
     }
     }
 
 
+    memset(inputString, 0x00, sizeof(inputString));
+    memset(normalCmd, 0x00, sizeof(normalCmd));
+
+    if(argc > 1)
+    {
+        for(int i = 0; i < argc - 1; i++)
+        {
+            strcat(inputString, argv[i + 1]);
+            if(i + 1 < argc - 1)
+            {
+                strcat(inputString, " ");
+            }
+        }
+    }
+
 	for(;;)
 	for(;;)
 	{
 	{
-        memset(inputString, 0x00, sizeof(inputString));
-        memset(normalCmd, 0x00, sizeof(normalCmd));
+	    if(argc == 1)
+	    {
+            memset(inputString, 0x00, sizeof(inputString));
+            memset(normalCmd, 0x00, sizeof(normalCmd));
+            get_char(inputString);
+	    }
 
 
-        get_char(inputString);
         cmdCnt = InputStringNormalize(inputString, normalCmd, &option);
         cmdCnt = InputStringNormalize(inputString, normalCmd, &option);
         if(cmdCnt > 0)
         if(cmdCnt > 0)
         {
         {
@@ -5772,9 +6207,9 @@ int main(void)
                 continue;
                 continue;
             }
             }
         }
         }
-        else if(strcmp(newString[0], "gdmd") == 0)
+        else if(strcmp(mainCmd, "gdmd") == 0)
         {
         {
-            ShowGroupingDemand();
+            ShowGroupingDemand(subCmd, option);
         }
         }
         else if(strcmp(mainCmd, "gunchg") == 0)
         else if(strcmp(mainCmd, "gunchg") == 0)
         {
         {
@@ -5905,12 +6340,21 @@ int main(void)
         else if(strcmp(mainCmd, "occupancy") == 0)
         else if(strcmp(mainCmd, "occupancy") == 0)
         {
         {
             ShowOccupancy(subCmd, option);
             ShowOccupancy(subCmd, option);
+        }
+        else if(strcmp(mainCmd, "super") == 0)
+        {
+            SuperMode(subCmd, option);
         }
         }
 		else
 		else
 		{
 		{
 			printf ("%s\n", msg);
 			printf ("%s\n", msg);
 		}
 		}
 		usleep(100000);
 		usleep(100000);
+
+        if(argc > 1)
+        {
+            break;
+        }
 	}
 	}
 
 
 	return 0;
 	return 0;

File diff suppressed because it is too large
+ 678 - 106
EVSE/Projects/DO360/Apps/main.c


Some files were not shown because too many files changed in this diff