瀏覽代碼

[Merge][DM30][DW30][Full function]: Merge DS60 V0.16 application source code

2020.08.13 / TC Hsu

Actions: Merge application code form DS60, except display functions that relative to alternative feature.

Image version    : N/A
Image checksum   : N/A

Hardware PWB P/N : N/A
Hardware Version : N/A

Files:

	modified:   EVSE/Projects/DM30/Apps/Config.h
	modified:   EVSE/Projects/DM30/Apps/FactoryConfig.c
	modified:   EVSE/Projects/DM30/Apps/Makefile
	modified:   EVSE/Projects/DM30/Apps/Module_EvComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_EventLogging.c
	modified:   EVSE/Projects/DM30/Apps/Module_InternalComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_LcmControl.c
	modified:   EVSE/Projects/DM30/Apps/Module_LcmControl.h
	modified:   EVSE/Projects/DM30/Apps/Module_PrimaryComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_PsuComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_PsuComm.h
	new file:   EVSE/Projects/DM30/Apps/OutputTask.c
	new file:   EVSE/Projects/DM30/Apps/OutputTask.h
	modified:   EVSE/Projects/DM30/Apps/ReadCmdline.c
	modified:   EVSE/Projects/DM30/Apps/main.c
	modified:   EVSE/Projects/DM30/Apps/timeout.h
	modified:   EVSE/Projects/DW30/Apps/Config.h
	modified:   EVSE/Projects/DW30/Apps/FactoryConfig.c
	modified:   EVSE/Projects/DW30/Apps/Makefile
	modified:   EVSE/Projects/DW30/Apps/Module_EvComm.c
	modified:   EVSE/Projects/DW30/Apps/Module_EventLogging.c
	modified:   EVSE/Projects/DW30/Apps/Module_InternalComm.c
	modified:   EVSE/Projects/DW30/Apps/Module_LcmControl.c
	modified:   EVSE/Projects/DW30/Apps/Module_LcmControl.h
	modified:   EVSE/Projects/DW30/Apps/Module_PrimaryComm.c
	modified:   EVSE/Projects/DW30/Apps/Module_PsuComm.c
	modified:   EVSE/Projects/DW30/Apps/Module_PsuComm.h
	new file:   EVSE/Projects/DW30/Apps/OutputTask.c
	new file:   EVSE/Projects/DW30/Apps/OutputTask.h
	modified:   EVSE/Projects/DW30/Apps/ReadCmdline.c
	modified:   EVSE/Projects/DW30/Apps/main.c
	modified:   EVSE/Projects/DW30/Apps/timeout.h
TC_Hsu 4 年之前
父節點
當前提交
63226710cf
共有 32 個文件被更改,包括 3504 次插入944 次删除
  1. 20 2
      EVSE/Projects/DM30/Apps/Config.h
  2. 7 3
      EVSE/Projects/DM30/Apps/FactoryConfig.c
  3. 10 3
      EVSE/Projects/DM30/Apps/Makefile
  4. 82 29
      EVSE/Projects/DM30/Apps/Module_EvComm.c
  5. 0 1
      EVSE/Projects/DM30/Apps/Module_EventLogging.c
  6. 243 101
      EVSE/Projects/DM30/Apps/Module_InternalComm.c
  7. 34 22
      EVSE/Projects/DM30/Apps/Module_LcmControl.c
  8. 4 0
      EVSE/Projects/DM30/Apps/Module_LcmControl.h
  9. 2 1
      EVSE/Projects/DM30/Apps/Module_PrimaryComm.c
  10. 251 136
      EVSE/Projects/DM30/Apps/Module_PsuComm.c
  11. 0 1
      EVSE/Projects/DM30/Apps/Module_PsuComm.h
  12. 373 0
      EVSE/Projects/DM30/Apps/OutputTask.c
  13. 174 0
      EVSE/Projects/DM30/Apps/OutputTask.h
  14. 188 20
      EVSE/Projects/DM30/Apps/ReadCmdline.c
  15. 363 153
      EVSE/Projects/DM30/Apps/main.c
  16. 1 0
      EVSE/Projects/DM30/Apps/timeout.h
  17. 20 2
      EVSE/Projects/DW30/Apps/Config.h
  18. 7 3
      EVSE/Projects/DW30/Apps/FactoryConfig.c
  19. 10 3
      EVSE/Projects/DW30/Apps/Makefile
  20. 82 29
      EVSE/Projects/DW30/Apps/Module_EvComm.c
  21. 0 1
      EVSE/Projects/DW30/Apps/Module_EventLogging.c
  22. 243 101
      EVSE/Projects/DW30/Apps/Module_InternalComm.c
  23. 34 22
      EVSE/Projects/DW30/Apps/Module_LcmControl.c
  24. 4 0
      EVSE/Projects/DW30/Apps/Module_LcmControl.h
  25. 2 1
      EVSE/Projects/DW30/Apps/Module_PrimaryComm.c
  26. 251 136
      EVSE/Projects/DW30/Apps/Module_PsuComm.c
  27. 0 1
      EVSE/Projects/DW30/Apps/Module_PsuComm.h
  28. 373 0
      EVSE/Projects/DW30/Apps/OutputTask.c
  29. 174 0
      EVSE/Projects/DW30/Apps/OutputTask.h
  30. 188 20
      EVSE/Projects/DW30/Apps/ReadCmdline.c
  31. 363 153
      EVSE/Projects/DW30/Apps/main.c
  32. 1 0
      EVSE/Projects/DW30/Apps/timeout.h

+ 20 - 2
EVSE/Projects/DM30/Apps/Config.h

@@ -30,7 +30,7 @@ typedef unsigned char           byte;
 #define MODE_DEBUG                  16
 #define MODE_CCS_PRECHARGE_STEP0    17  // ready for ccs precharge processing, For D+ relay to precharge relay
 #define MODE_CCS_PRECHARGE_STEP1    18  // waitting for ev board inform to enter to charging, For precharge relay to D+ relay
-#define MODE_SINGLE_RUN             19
+#define MODE_UPDATE                 19
 
 #define GFD_WAIT                    0
 #define GFD_PASS                    1
@@ -66,7 +66,7 @@ enum _SYSTEM_STATUS
     S_DEBUG                             = 16,
     S_CCS_PRECHARGE_ST0                 = 17,
     S_CCS_PRECHARGE_ST1                 = 18,
-    S_SINGLE_RUN                        = 19,
+    S_UPDATE                            = 19,
     S_NONE                              = 20,
 };
 
@@ -119,7 +119,11 @@ enum _MODULE_PSU_WORK_STEP
     GET_PSU_COUNT                       = 1,
     GET_SYS_CAP                         = 2,
     BOOTING_COMPLETE                    = 3,
+
     _WORK_CHARGING                      = 10,
+
+    _TEST_MODE                          = 20,
+
     _NO_WORKING                         = 254,
     _INIT_PSU_STATUS                    = 255,
 };
@@ -174,4 +178,18 @@ enum _SYS_WIFI_MODE
     _SYS_WIFI_MODE_ADHOC                = 3,
 };
 
+enum _LED_INTENSITY_LV
+{
+    _LED_INTENSITY_DARKEST              = 0,
+    _LED_INTENSITY_MEDIUM               = 1,
+    _LED_INTENSITY_BRIGHTEST            = 2,
+};
+
+enum _CCS_COMM_PROTOCOL
+{
+    _CCS_COMM_V2GMessage_DIN70121       = 0x01,
+    _CCS_COMM_V2GMessage_ISO15118_2014  = 0x02,
+    _CCS_COMM_V2GMessage_ISO15118_2018  = 0x03,
+};
+
 #endif /* CONFIG_H_ */

+ 7 - 3
EVSE/Projects/DM30/Apps/FactoryConfig.c

@@ -106,7 +106,7 @@ int main(int argc,char *argv[])
     //********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
     //
     strcpy((char *)SysConfig.ModelName, "DMYE301E00W2PH");
-    strcpy((char *)SysConfig.SerialNumber, "");
+    strcpy((char *)SysConfig.SerialNumber, "NeedSetupSN");
 
     memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
     char Dash = '-';
@@ -130,7 +130,7 @@ int main(int argc,char *argv[])
     SysConfig.isRFID = 1;
     //********** Charging **********//
     SysConfig.MaxChargingEnergy = 0;
-    SysConfig.MaxChargingCurrent = 60;      // 最大可輸出電流
+    SysConfig.MaxChargingCurrent = 60;      // 最大可輸出電流 (整樁)
     SysConfig.MaxChargingDuration = 0;
     SysConfig.AcMaxChargingCurrent = 0;
     SysConfig.PhaseLossPolicy = LOSS_POLICY_STOP;
@@ -148,7 +148,10 @@ int main(int argc,char *argv[])
     strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
     strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
     strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
-    SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_AP;
+    if(SysConfig.ModelName[10] == 'W')
+        SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_AP;
+    else
+        SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_DISABLE;
     strcpy((char *) SysConfig.AthInterface.WifiSsid, "");
     strcpy((char *) SysConfig.AthInterface.WifiPassword, "");
     SysConfig.AthInterface.WifiRssi = 0;
@@ -183,6 +186,7 @@ int main(int argc,char *argv[])
     //strcpy((char *) SysConfig.ChargeBoxId, "DemoDC");
     strcpy((char *) SysConfig.OcppServerURL, "");
     strcpy((char *) SysConfig.ChargeBoxId, "");
+    SysConfig.LedInfo.Intensity = 2;
 
     //copy default configuration to pointer
     memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));

+ 10 - 3
EVSE/Projects/DM30/Apps/Makefile

@@ -2,19 +2,20 @@
 export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)/usr/bin:$PATH
 
 #define library variable
-Internal485ProtocolLib = -L ../../../Modularization/Internal485Protocol -lInternal485Protocol
+Lib_Module_RFID = "-L../../../Modularization" -lModule_RFID
+Lib_Module_Upgrade = "-L../../../Modularization" -lModule_Upgrade
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
 all: CreateOutputFolder BuildFactorys BuildApps CopyExecuteFiles Clean
 
 BuildFactorys: FactoryConfigBin
 
-BuildApps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask FactoryConfigApp
+BuildApps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask FactoryConfigApp UnsafetyOutputTool
 
 MainTask:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -include../../../Modularization/ocppfiles/sqlite3.h -include../../../Modularization/Module_RFID.h -include../../../Modularization/Module_Upgrade.h -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.c
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -O0 -g3 -Wall -c -fmessage-length=0 -o timeout.o timeout.c
-	$(CC) -o main main.o timeout.o ../../../Modularization/libModule_RFID.a ../../../Modularization/libModule_Upgrade.a ${Lib_SQLite3}
+	$(CC) -o main main.o timeout.o ${Lib_Module_RFID} ${Lib_Module_Upgrade} ${Lib_SQLite3}
 
 EvCommTask:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Ev_Comm.o Ev_Comm.c
@@ -51,6 +52,10 @@ FactoryConfigApp:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -O0 -g3 -Wall -c -fmessage-length=0 -o FactoryConfig.o FactoryConfig.c
 	$(CC) -o FactoryConfig FactoryConfig.o
 
+UnsafetyOutputTool:
+	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -O0 -g3 -Wall -c -fmessage-length=0 -o OutputTask.o OutputTask.c
+	$(CC) -o UnsafetyOutputTask OutputTask.o ../../../Modularization/libInfypwr_PsuCommObj.a
+
 FactoryConfigBin:
 	gcc -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) "-I../../" -o FactoryConfig "./FactoryConfig.c"
 	mkdir -p /Storage/SystemLog
@@ -76,6 +81,7 @@ CopyExecuteFiles: OtherTools
 	cp -f Module_PsuComm ../Images/root
 	cp -f ReadCmdline ../Images/root
 	cp -f FactoryConfig ../Images/root
+	cp -f UnsafetyOutputTask ../Images/root
 
 Clean: CleanObj CleanExecute
 
@@ -92,3 +98,4 @@ CleanExecute:
 	rm -f Module_PsuComm
 	rm -f ReadCmdline
 	rm -f FactoryConfig
+	rm -f UnsafetyOutputTask

+ 82 - 29
EVSE/Projects/DM30/Apps/Module_EvComm.c

@@ -49,6 +49,7 @@ struct CcsData                  *ShmCcsData;
 
 byte gun_count;
 int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+struct timeval _chk_ratingPower_timeout[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 float _pow_1 = 0;
 float _cur_1 = 0;
@@ -1786,6 +1787,20 @@ void ClearAbnormalStatus_CCS(byte gun_index)
         memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
         isCleanCheck = true;
     }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023818", 6) == EQUAL &&
+            ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound == YES)
+    {
+        memcpy(code, "023818", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023819", 6) == EQUAL &&
+            ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq == YES)
+    {
+        memcpy(code, "023819", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
     else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023823", 6) == EQUAL &&
              ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join == YES)
     {
@@ -2213,6 +2228,13 @@ void ClearAbnormalStatus_CCS(byte gun_index)
         memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
         isCleanCheck = true;
     }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023893", 6) == EQUAL &&
+             ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey == YES)
+    {
+        memcpy(code, "023893", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
 
     if (isCleanCheck)
     {
@@ -2300,6 +2322,8 @@ void ClearAbnormalStatus_CCS(byte gun_index)
                     if (strncmp(code, "023815", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_EVSE_match_session = NO;
                     if (strncmp(code, "023816", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_assoc_session = NO;
                     if (strncmp(code, "023817", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_vald_toggle = NO;
+                    if (strncmp(code, "023818", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound = NO;
+                    if (strncmp(code, "023819", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq = NO;
                     if (strncmp(code, "023823", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join = NO;
                     if (strncmp(code, "023824", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTCP_TT_match_join = NO;
                     if (strncmp(code, "023825", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_amp_map_exchange = NO;
@@ -2361,6 +2385,7 @@ void ClearAbnormalStatus_CCS(byte gun_index)
                     if (strncmp(code, "023890", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUnexpectVolBeforeCharing_Error = NO;
                     if (strncmp(code, "023891", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccNotReadyForCharging = NO;
                     if (strncmp(code, "023892", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = NO;
+                    if (strncmp(code, "023893", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey = NO;
                 }
             }
         }
@@ -2378,7 +2403,7 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
         return;
 
     memcpy(_chargingData[gun_index]->EvConnAlarmCode, string, 6);
-    printf("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s \n", _chargingData[gun_index]->EvConnAlarmCode);
+    PRINTF_FUNC("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s \n", _chargingData[gun_index]->EvConnAlarmCode);
 
     if (strcmp(string, "023700") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoEvCommFail = YES;
     if (strcmp(string, "023704") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoBatteryMalfun = YES;
@@ -2492,6 +2517,8 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
     if (strcmp(string, "023815") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_EVSE_match_session = YES;
     if (strcmp(string, "023816") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_assoc_session = YES;
     if (strcmp(string, "023817") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_vald_toggle = YES;
+    if (strcmp(string, "023818") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound = YES;
+    if (strcmp(string, "023819") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq = YES;
     if (strcmp(string, "023823") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join = YES;
     if (strcmp(string, "023824") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTCP_TT_match_join = YES;
     if (strcmp(string, "023825") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_amp_map_exchange = YES;
@@ -2553,6 +2580,7 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
     if (strcmp(string, "023890") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUnexpectVolBeforeCharing_Error = YES;
     if (strcmp(string, "023891") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccNotReadyForCharging = YES;
     if (strcmp(string, "023892") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = YES;
+    if (strcmp(string, "023893") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey = YES;
 
     if (strcmp(string, "023702") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.GbEvCommFail = YES;
     if (strcmp(string, "023900") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = YES;
@@ -2649,6 +2677,8 @@ void CANReceiver()
                     break;
                 }
             }
+
+            sleep(1);
         }
 
         for (byte _index = 0; _index < gun_count; _index++)
@@ -2738,7 +2768,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if (ShmCcsData->CommProtocol == 0x01)
+                            if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 for (byte _vCount = 0, _vPoint = 0; _vCount < frame.can_dlc; _vCount++)
                                 {
@@ -2777,8 +2807,8 @@ void CANReceiver()
                     case ACK_GET_OUTPUT_REQ:
                     {
                         _chargingData[targetGun]->EvBatterySoc = frame.data[1];
-                        _chargingData[targetGun]->EvBatterytargetVoltage = (((short) frame.data[3] << 8) + (short) frame.data[2]) / 10;
-                        _chargingData[targetGun]->EvBatterytargetCurrent = (((short) frame.data[5] << 8) + (short) frame.data[4]) / 10;
+                        _chargingData[targetGun]->EvBatterytargetVoltage = (float)((frame.data[3] << 8) + frame.data[2]) / 10;
+                        _chargingData[targetGun]->EvBatterytargetCurrent = (float)((frame.data[5] << 8) + frame.data[4]) / 10;
                         _chargingData[targetGun]->RemainChargingDuration = ((short) frame.data[7] << 8) + (short) frame.data[6];
 
                         if (_chargingData[targetGun]->Type == _Type_Chademo)
@@ -2799,7 +2829,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if(ShmCcsData->CommProtocol == 0x01)
+                            if(ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index].PresentMsgFlowStatus = frame.data[0];
                             }
@@ -2857,7 +2887,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if (ShmCcsData->CommProtocol == 0x01)
+                            if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 //ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index]. .ConnectorTemperatureP = frame.data[1];
                                 //ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index]. .ConnectorTemperatureN = frame.data[2];
@@ -2995,6 +3025,7 @@ void Initialization()
                 break;
             }
         }
+        sleep(1);
     }
 }
 
@@ -3152,7 +3183,7 @@ byte GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
         }
         else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip == YES)
         {
-            // 012236
+            // 012235
             *(reason + 5) = 0;
             *(reason + 4) = 1;
             *(reason + 3) = 2;
@@ -3209,7 +3240,7 @@ int main(int argc, char *argv[])
                 }
                 else if (_chargingData[_index]->Type == _Type_CCS_2)
                 {
-                    if (ShmCcsData->CommProtocol == 0x01 &&
+                    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121 &&
                         ShmCcsData->V2GMessage_DIN70121[_chargingData[_index]->type_index].SelfTest_Comp != PASS)
                     {
                         SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
@@ -3268,6 +3299,8 @@ int main(int argc, char *argv[])
                         SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
                     else if (gun_count == 2)
                         SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+
+                    _chargingData[_index]->PowerConsumption = 0;
                 }
                     break;
                 case S_PREPARING_FOR_EV:
@@ -3309,6 +3342,7 @@ int main(int argc, char *argv[])
                         // 取得車端電池資訊 : 1.AC or DC ? 2.Total battery cap, 3.Max battery vol, 4.Max battery cur
                         GetEvBatteryInfo(_index, _chargingData[_index]->Evboard_id);
                     }
+                    gettimeofday(&_chk_ratingPower_timeout[_index], NULL);
                 }
                     break;
                 case S_PREPARING_FOR_EVSE:
@@ -3342,9 +3376,9 @@ int main(int argc, char *argv[])
 
                         //PRINTF_FUNC("To EV_%d GFD = %d \n",   _index, _chargingData[_index]->GroundFaultStatus);
 
-                        unsigned char _result = GFD_WAIT;
-                        _result = _chargingData[_index]->GroundFaultStatus;
+                        unsigned char _result = _chargingData[_index]->GroundFaultStatus;
 
+                        // GB & Chademo ~ Warning 也先算 Pass,因為 CCS 認證會驗 Warning 故不可更動
                         if(_chargingData[_index]->Type == _Type_Chademo ||
                            _chargingData[_index]->Type == _Type_GB)
                         {
@@ -3360,6 +3394,19 @@ int main(int argc, char *argv[])
                             PRINTF_FUNC("Unexpected GFD status : %d \n", _result);
                             _result = GFD_WAIT;
                         }
+                        else if (_result == GFD_WARNING ||
+                                 _result == GFD_PASS)
+                        {
+                            if (((GetTimeoutValue(_chk_ratingPower_timeout[_index]) / 1000) > 12000 &&
+                                 _chargingData[_index]->RealRatingPower > 0) ||
+                                (GetTimeoutValue(_chk_ratingPower_timeout[_index]) / 1000) > 14000)
+                            {
+                                PRINTF_FUNC("**********EvComm : _index= %d, RealRatingPower = %d \n",
+                                            _index, _chargingData[_index]->RealRatingPower);
+                            }
+                            else
+                                _result = GFD_WAIT;
+                        }
 
                         SetIsolationStatus(_index, _result, _chargingData[_index]->Evboard_id);
 
@@ -3376,7 +3423,8 @@ int main(int argc, char *argv[])
                     // 計算 Power
                     _chargingData[_index]->PresentChargingPower = ((float)((_chargingData[_index]->PresentChargingVoltage) * (_chargingData[_index]->PresentChargingCurrent)) / 1000);
 
-                    if (chargingTime[_index] == 0)
+                    if (chargingTime[_index] == 0 ||
+                        chargingTime[_index] > _chargingData[_index]->PresentChargedDuration)
                     {
                         chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
                     }
@@ -3393,6 +3441,7 @@ int main(int argc, char *argv[])
                             }
 
                             _chargingData[_index]->PresentChargedEnergy += changingPow;
+                            _chargingData[_index]->PowerConsumption += changingPow;
                             chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
                         }
                     }
@@ -3416,26 +3465,18 @@ int main(int argc, char *argv[])
                             SetPresentChargingOutputCap(_chargingData[0], _chargingData[1]);
                     }
 
-                    if (priorityLow == 1)
+                    if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
                     {
-                        // Chademo & GB/T GFD 失敗再通知
-                        if(_chargingData[_index]->Type == _Type_Chademo || _chargingData[_index]->Type == _Type_GB)
-                        {
-                            if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
-                            {
-                                SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
-                            }
-                        }
-                        // CCS will be continuous notify GFD state
-                        else if(_chargingData[_index]->Type == _Type_CCS_2)
-                        {
-                            SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
-                        }
-                        else
-                        {
-                            //NULL
-                        }
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
+                    else if(_chargingData[_index]->Type == _Type_CCS_2)
+                    {
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
 
+                    // GFD 失敗再通知
+                    if (priorityLow == 1)
+                    {
                         if(_chargingData[_index]->Type == _Type_CCS_2 &&
                            _chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
                         {
@@ -3466,11 +3507,23 @@ int main(int argc, char *argv[])
 
                         EvseStopChargingEvent(normalStop, stopReason, _chargingData[_index]->Evboard_id);
                     }
+
+                    if(_chargingData[_index]->Type == _Type_CCS_2)
+                    {
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
+
                     GetOutputReq(_index, _chargingData[_index]->Evboard_id);
                 }
                     break;
                 case S_COMPLETE:
                 {
+                    // 設定當前輸出
+                    if (gun_count == 1)
+                        SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
+                    else if (gun_count == 2)
+                        SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+
                     if (priorityLow == 1)
                     {
                         float maxVol, maxCur;

+ 0 - 1
EVSE/Projects/DM30/Apps/Module_EventLogging.c

@@ -180,7 +180,6 @@ void RemoveFaultCodeToBuf(unsigned char *Code)
     char _code[7];
     sprintf(_code,"%s", Code);
 
-    printf("********************* %s \n", _code);
     // 把相關的錯誤碼一次移除,避免重複顯示
     while(find)
     {

+ 243 - 101
EVSE/Projects/DM30/Apps/Module_InternalComm.c

@@ -46,16 +46,20 @@
 
 #define AC_DEFAULT_VOL      220
 
+#define NO_DEFINE           255
+#define NDEFAULT_AC_INDEX   2
+
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct FanModuleData            *ShmFanModuleData;
 struct RelayModuleData          *ShmRelayModuleData;
 struct LedModuleData            *ShmLedModuleData;
 struct PsuData                  *ShmPsuData;
+struct OCPP16Data               *ShmOCPP16Data;
 
 #define VIN_MAX_VOLTAGE_IEC     285 // 大於該值 : OVP
 #define VIN_MIN_VOLTAGE_IEC     160 // 小於該值 : UVP
-#define VIN_MAX_VOLTAGE_UL      315 // 大於該值 : OVP
+#define VIN_MAX_VOLTAGE_UL      315 // 大於該值 : OVP // 美規 (W)
 #define VIN_MIN_VOLTAGE_UL      210 // 小於該值 : UVP
 
 #define VIN_DROP_VOLTAGE    150 // 小於該值 : ac drop
@@ -64,7 +68,7 @@ struct PsuData                  *ShmPsuData;
 #define VOUT_MIN_VOLTAGE    150
 #define IOUT_MAX_CURRENT    50
 
-#define MAX_FAN_SPEED       13500
+#define MAX_FAN_SPEED       14000
 #define MIN_FAN_SPEED       3000
 #define NORMAL_FAN_SPEED    7000
 
@@ -74,6 +78,16 @@ struct PsuData                  *ShmPsuData;
 #define GFD_PRECHARGE       2
 #define GFD_CHARGING        3
 
+// LED Intensity (rate)
+#define LED_INTENSITY_DARKEST       0.2
+#define LED_INTENSITY_MEDIUM        0.6
+#define LED_INTENSITY_BRIGHTEST     1
+
+// EE Spec
+#define LED_BRIGHTNESS_LV_HIGH      1
+#define LED_BRIGHTNESS_LV_MID       0.5
+#define LED_BRIGHTNESS_LV_LOW       0.2
+
 // 最小切換 Relay 電壓
 #define SELF_TO_CHANGE_RELAY_STATUS         600
 // 透過電壓確認 Relay 是否搭上的依據電壓
@@ -415,7 +429,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
             }
             else
@@ -423,7 +437,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
             }
             else
@@ -431,7 +445,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
             }
             else
@@ -441,7 +455,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
             }
             else
@@ -449,7 +463,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
             }
             else
@@ -457,7 +471,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
             }
             else
@@ -469,7 +483,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
             }
             else
@@ -477,7 +491,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
             }
             else
@@ -485,7 +499,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
             }
             else
@@ -495,7 +509,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
             }
             else
@@ -503,7 +517,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
             }
             else
@@ -511,7 +525,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
             }
             else
@@ -822,17 +836,14 @@ void GetAuxPower()
 
 void SetFanModuleSpeed()
 {
-    // 調整風扇速度要漸進式 : 500 rpm/p
     FanSpeed _fanSpeed;
 
     _setFanSpeed += fanSpeedSmoothValue;
 
     if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
         _setFanSpeed = ShmFanModuleData->SetFan1Speed;
-    {
-        _fanSpeed.speed[0] = _setFanSpeed;
-    }
 
+    _fanSpeed.speed[0] = _setFanSpeed;
     _fanSpeed.speed[1] = _setFanSpeed;
     _fanSpeed.speed[2] = _setFanSpeed;
     _fanSpeed.speed[3] = _setFanSpeed;
@@ -847,6 +858,15 @@ void SetFanModuleSpeed()
 //==========================================
 void SetK1K2RelayStatus(byte index)
 {
+    if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+    {
+        if(regRelay.relay_event.bits.Gun1_N == NO)
+            outputRelay.relay_event.bits.Gun1_N = YES;
+        else if (regRelay.relay_event.bits.Gun1_P == NO)
+            outputRelay.relay_event.bits.Gun1_P = YES;
+        return;
+    }
+
     if (_chargingData[index]->SystemStatus < S_PREPARING_FOR_EVSE)
     {
         if (_chargingData[index]->Evboard_id == 0x01)
@@ -1135,15 +1155,22 @@ bool IsNoneMatchLedColor()
 
 void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
 {
-    if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
+    byte _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST;
+
+    if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_DARKEST)
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST;
+    else if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_MEDIUM)
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM;
+
+    if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf)
     {
         if ((chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION) &&
             (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION))
         {
-            led_color.Connect_1_Green   = COLOR_MAX_LV;
+            led_color.Connect_1_Green   = _colorBuf;
             led_color.Connect_1_Blue    = COLOR_MIN_LV;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
-            led_color.Connect_2_Green   = COLOR_MAX_LV;
+            led_color.Connect_2_Green   = _colorBuf;
             led_color.Connect_2_Blue    = COLOR_MIN_LV;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
@@ -1153,10 +1180,10 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_1_Green   = COLOR_MIN_LV;
-            led_color.Connect_1_Blue    = COLOR_MAX_LV;
+            led_color.Connect_1_Blue    = _colorBuf;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
             led_color.Connect_2_Green   = COLOR_MIN_LV;
-            led_color.Connect_2_Blue    = COLOR_MAX_LV;
+            led_color.Connect_2_Blue    = _colorBuf;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
     }
@@ -1164,7 +1191,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
     {
         if (chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION)
         {
-            led_color.Connect_1_Green   = COLOR_MAX_LV;
+            led_color.Connect_1_Green   = _colorBuf;
             led_color.Connect_1_Blue    = COLOR_MIN_LV;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
         }
@@ -1172,14 +1199,14 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_1_Green   = COLOR_MIN_LV;
-            led_color.Connect_1_Blue    = COLOR_MAX_LV;
+            led_color.Connect_1_Blue    = _colorBuf;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
         }
 
         // --------------------------------------------------------------------------
         if (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION)
         {
-            led_color.Connect_2_Green   = COLOR_MAX_LV;
+            led_color.Connect_2_Green   = _colorBuf;
             led_color.Connect_2_Blue    = COLOR_MIN_LV;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
@@ -1187,7 +1214,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_2_Green   = COLOR_MIN_LV;
-            led_color.Connect_2_Blue    = COLOR_MAX_LV;
+            led_color.Connect_2_Blue    = _colorBuf;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
     }
@@ -1196,10 +1223,10 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
     {
         led_color.Connect_1_Green   = COLOR_MIN_LV;
         led_color.Connect_1_Blue    = COLOR_MIN_LV;
-        led_color.Connect_1_Red     = COLOR_MAX_LV;
+        led_color.Connect_1_Red     = _colorBuf;
         led_color.Connect_2_Green   = COLOR_MIN_LV;
         led_color.Connect_2_Blue    = COLOR_MIN_LV;
-        led_color.Connect_2_Red     = COLOR_MAX_LV;
+        led_color.Connect_2_Red     = _colorBuf;
     }
 
     if (_checkLedChanged > 0)
@@ -1227,7 +1254,6 @@ int InitShareMemory()
     int result = PASS;
     int MeterSMId;
 
-    //creat ShmSysConfigAndInfo
     if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1242,7 +1268,7 @@ int InitShareMemory()
         #endif
         result = FAIL;
      }
-     //creat ShmStatusCodeData
+
     if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1258,7 +1284,6 @@ int InitShareMemory()
         result = FAIL;
     }
 
-    //creat ShmFanModuleData
     if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1275,7 +1300,6 @@ int InitShareMemory()
      }
      memset(ShmFanModuleData,0,sizeof(struct FanModuleData));
 
-     //creat ShmRelayModuleData
     if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1292,7 +1316,6 @@ int InitShareMemory()
     }
     memset(ShmRelayModuleData,0,sizeof(struct RelayModuleData));
 
-    //creat ShmLedModuleData
     if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1309,7 +1332,6 @@ int InitShareMemory()
     }
     memset(ShmLedModuleData,0,sizeof(struct LedModuleData));
 
-    //creat ShmPsuData
     if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1325,6 +1347,21 @@ int InitShareMemory()
         result = FAIL;
     }
 
+    if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ShmOCPP16Data NG \n");
+        #endif
+        result = FAIL;
+    }
+    else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ShmOCPP16Data NG \n");
+        #endif
+        result = FAIL;
+    }
+
     return result;
 }
 
@@ -1427,6 +1464,8 @@ void Initialization()
                 break;
             }
         }
+
+        sleep(1);
     }
 
     isPass = false;
@@ -1445,6 +1484,8 @@ void Initialization()
                     break;
                 }
             }
+
+            sleep(1);
         }
     }
 }
@@ -1546,7 +1587,7 @@ void CableCheckDetected(byte index)
     if ((_chargingData[index]->Type >= _Type_Chademo && _chargingData[index]->Type <= _Type_GB) ||
         (_chargingData[index]->Type == 0x09 && ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag))
     {
-        if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_CHARGING) ||
+        if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_TERMINATING) ||
             (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE &&
@@ -1559,16 +1600,13 @@ void CableCheckDetected(byte index)
             {
                 SetGfdConfig(index, GFD_PRECHARGE);
             }
-            else if (_chargingData[index]->SystemStatus <= S_CHARGING)
+            else if (_chargingData[index]->SystemStatus >= S_CHARGING &&
+                     _chargingData[index]->SystemStatus <= S_TERMINATING)
             {
-                if (_chargingData[index]->Type == _Type_CCS_2)
-                {
-                    SetGfdConfig(index, GFD_CHARGING);
-                }
-                else
-                {
+                if (_chargingData[index]->Type == _Type_GB || _chargingData[index]->Type == _Type_Chademo)
                     SetGfdConfig(index, GFD_IDLE);
-                }
+                else
+                    SetGfdConfig(index, GFD_CHARGING);
             }
         }
         else if(_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING
@@ -1668,6 +1706,7 @@ void CheckRelayWeldingStatus(byte index)
 void GetPsuTempForFanSpeed()
 {
     char temp = 0;
+
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
     {
         for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
@@ -1677,6 +1716,8 @@ void GetPsuTempForFanSpeed()
         }
     }
 
+    ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = temp;
+
     if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO)
     {
         if (ShmFanModuleData->TestFanSpeed == NORMAL_FAN_SPEED)
@@ -1694,6 +1735,65 @@ void GetPsuTempForFanSpeed()
     }
 }
 
+void GetFanSpeedByFunction()
+{
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
+        return;
+
+    // 風控修改 :
+    // ******************************************************* //
+    //
+    //       當前PSU輸出總 KW       PSU Temp
+    // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
+    //       當前樁最大功率 KW         45
+    //
+    // ******************************************************* //
+
+    // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower
+    unsigned int _maxPower = ShmPsuData->SystemAvailablePower;
+    // 當前PSU輸出總 KW & PSU Temp :
+    unsigned char temp = 0;
+    float power = 0;
+
+    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+    {
+        for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
+        {
+            if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp)
+                temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp;
+        }
+        power += (_chargingData[index]->PresentChargingPower * 10);
+    }
+
+    double _pw_rate = 0;
+    if (_maxPower > 0)
+        _pw_rate = power / (double)_maxPower;
+    double _temp_rate = 0;
+    if (temp > 0)
+        _temp_rate = (double)temp / 45;
+    unsigned char _temp_diff = 0;
+    if (temp > 45)
+        _temp_diff = temp - 45;
+
+    ShmFanModuleData->TestFanSpeed = ((30 * _pw_rate * _temp_rate + 14 * _temp_diff) / 100) * MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED)
+        ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed < 0)
+            ShmFanModuleData->TestFanSpeed = 0;
+//
+//  printf("power = %f \n", power);
+//  printf("_maxPower = %d \n", _maxPower);
+//  printf("temp = %d \n", temp);
+//
+//  printf("_pw_rate = %f \n", _pw_rate);
+//  printf("_temp_rate = %f \n", _temp_rate);
+//  printf("_temp_diff = %d \n", _temp_diff);
+//  printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff));
+//  printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed);
+}
+
 void GetAcStatus()
 {
     if (Query_AC_Status(Uart5Fd, Addr.AcPlug, &acStatus) == PASS)
@@ -1789,10 +1889,61 @@ void ChangeStartOrStopDateTime(byte isStart)
         strcpy((char *)ac_chargingInfo[0]->StopDateTime, cmdBuf);
 }
 
+void OcppStartTransation(byte gunIndex)
+{
+    if(strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL)
+        strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag);
+    else
+        strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId);
+
+    PRINTF_FUNC("AC IdTag = %s \n", ShmOCPP16Data->StartTransaction[gunIndex].IdTag);
+    ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionReq = YES;
+}
+
+void OcppStopTransation(byte gunIndex)
+{
+    if(strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL)
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag);
+    else
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId);
+
+    PRINTF_FUNC("AC IdTag = %s \n", ShmOCPP16Data->StopTransaction[gunIndex].IdTag);
+    ShmOCPP16Data->CpMsg.bits[gunIndex].StopTransactionReq = YES;
+}
+
+bool OcppRemoteStop(byte gunIndex)
+{
+    bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq;
+
+    if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES)
+    {
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Remote");
+        ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO;
+    }
+
+    return result;
+}
+
+unsigned char isModeChange()
+{
+    unsigned char result = NO;
+
+    if(ac_chargingInfo[0]->SystemStatus != ac_chargingInfo[0]->PreviousSystemStatus)
+    {
+        result = YES;
+        ac_chargingInfo[0]->PreviousSystemStatus = ac_chargingInfo[0]->SystemStatus;
+    }
+
+    return result;
+}
+
 void AcChargeTypeProcess()
 {
     if (acgunCount > 0)
     {
+        //ac_chargingInfo[0]->SelfTest_Comp = YES;
+        //ac_chargingInfo[0]->IsModeChagned = PASS;
+        //---------------------------------------------
         if (ac_chargingInfo[0]->SelfTest_Comp == NO)
         {
             ac_chargingInfo[0]->IsModeChagned = NO;
@@ -1810,15 +1961,18 @@ void AcChargeTypeProcess()
             GetAcAlarmCode();
 
             byte _status = S_NONE;
-            bool _isStatusChanged = false;
 
-            if (acStatus.CpStatus == AC_SYS_A || ac_chargingInfo[0]->IsErrorOccur)
+            if (ac_chargingInfo[0]->SystemStatus == S_IDLE && ac_chargingInfo[0]->IsErrorOccur)
+            {
+                _status = S_ALARM;
+            }
+            else if (acStatus.CpStatus == AC_SYS_A || ac_chargingInfo[0]->IsErrorOccur)
             {
                 if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
                     _status = S_TERMINATING;
                 else if (ac_chargingInfo[0]->SystemStatus >= S_TERMINATING)
                 {
-                    if (GetTimeoutValue(_ac_charging_comp) >= 10000000)
+                    if (GetTimeoutValue(_ac_charging_comp) >= 10000000 && acStatus.CpStatus == AC_SYS_A)
                         _status = S_IDLE;
                 }
                 else
@@ -1832,21 +1986,21 @@ void AcChargeTypeProcess()
                 else if (GetTimeoutValue(_ac_preparing) >= 30000000)
                     _status = S_IDLE;
             }
-            else if (acStatus.CpStatus == AC_SYS_B &&
+            else if ((acStatus.CpStatus == AC_SYS_B || ac_chargingInfo[0]->ConnectorPlugIn == AC_SYS_B) &&
                      ac_chargingInfo[0]->IsAvailable &&
                      !ac_chargingInfo[0]->IsErrorOccur &&
                      (ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
                       ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE))
             {
-                if (ShmSysConfigAndInfo->SysInfo.OrderCharging != FAIL &&
-                    ShmSysConfigAndInfo->SysInfo.OrderCharging == DEFAULT_AC_INDEX)
+                if (ac_chargingInfo[0]->RemoteStartFlag == YES)
                 {
                     PRINTF_FUNC("** AC Remote \n");
+                    ac_chargingInfo[0]->RemoteStartFlag = NO;
                     strcpy((char *)ac_chargingInfo[0]->StartUserId, "");
                     ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO;
                     _status = S_PREPARNING;
                 }
-                else
+                else if (ShmSysConfigAndInfo->SysInfo.OrderCharging == NO_DEFINE)
                 {
                     PRINTF_FUNC("** UserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
                     strcpy((char *)ac_chargingInfo[0]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId);
@@ -1856,12 +2010,16 @@ void AcChargeTypeProcess()
                     _status = S_PREPARNING;
                 }
             }
+            else if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
+            {
+                if (OcppRemoteStop(1))
+                    _status = S_TERMINATING;
+            }
 
             //printf("_status = %d \n", _status);
 
             if (_status != S_NONE && ac_chargingInfo[0]->SystemStatus != _status)
             {
-                _isStatusChanged = true;
                 ac_chargingInfo[0]->SystemStatus = _status;
             }
 
@@ -1869,12 +2027,15 @@ void AcChargeTypeProcess()
             switch(ac_chargingInfo[0]->SystemStatus)
             {
                 case S_IDLE:
+                case S_ALARM:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ac_chargingInfo[0]->PresentChargedEnergy = 0.0;
                         ac_chargingInfo[0]->PresentChargingVoltage = 0;
                         ac_chargingInfo[0]->ChargingFee = 0.0;
+                        strcpy((char *)ac_chargingInfo[0]->StartDateTime, "");
+                        strcpy((char *)ac_chargingInfo[0]->StopDateTime, "");
                         _beforeChargingTotalEnergy = 0.0;
                     }
 
@@ -1883,16 +2044,18 @@ void AcChargeTypeProcess()
                     break;
                 case S_PREPARNING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
                         ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
-                        ShmSysConfigAndInfo->SysInfo.OrderCharging = FAIL;
+                        if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE)
+                            ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE;
                         gettimeofday(&_ac_preparing, NULL);
                     }
 
                     if (GetChargingEnergy() == PASS)
                     {
+                        //ac_chargingInfo[0]->PresentChargedEnergy = acChargingEnergy.Energy / 100;
                         _beforeChargingTotalEnergy = acChargingEnergy.Energy;
                     }
 
@@ -1902,9 +2065,10 @@ void AcChargeTypeProcess()
                     break;
                 case S_CHARGING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ftime(&_ac_startChargingTime);
+                        OcppStartTransation(1);
                         ChangeStartOrStopDateTime(YES);
                         ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
                     }
@@ -1924,12 +2088,12 @@ void AcChargeTypeProcess()
                     }
 
                     if (GetChargingCurrent() == PASS)
-                        ac_chargingInfo[0]->PresentChargingPower = (AC_DEFAULT_VOL * (acChargingCurrent.OuputCurrentL1 / 10)) / 1000;
+                        ac_chargingInfo[0]->PresentChargingPower = (((float)(AC_DEFAULT_VOL * acChargingCurrent.OuputCurrentL1) / 10) / 1000);
 
                     ftime(&_ac_endChargingTime);
                     ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
                     ac_chargingInfo[0]->PresentChargingVoltage = AC_DEFAULT_VOL;
-                    ac_chargingInfo[0]->PresentChargingCurrent = acChargingCurrent.OuputCurrentL1 / 10;
+                    ac_chargingInfo[0]->PresentChargingCurrent = ((float)acChargingCurrent.OuputCurrentL1 / 10);
 
                     // 用以判斷是否有在輸出
                     ac_chargingInfo[0]->IsCharging = acStatus.RelayStatus;
@@ -1940,7 +2104,7 @@ void AcChargeTypeProcess()
                     break;
                 case S_TERMINATING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ChangeStartOrStopDateTime(NO);
                         gettimeofday(&_ac_charging_comp, NULL);
@@ -1953,10 +2117,16 @@ void AcChargeTypeProcess()
                     break;
                 case S_COMPLETE:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         gettimeofday(&_ac_charging_comp, NULL);
                         ftime(&_ac_endChargingTime);
+                        if (strcmp((char *)ac_chargingInfo[0]->StartDateTime, "") != EQUAL)
+                        {
+                            // AC 固定為第2把槍
+                            OcppStopTransation(1);
+                        }
+
                         ChangeStartOrStopDateTime(NO);
                         ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
                     }
@@ -2124,7 +2294,9 @@ int main(void)
             // 橋接 relay
             SetParalleRelayStatus();
 
-            if (isCharging)
+            // 搭上 AC Contactor
+            if (isCharging ||
+                (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE))
             {
                 isStopChargingCount = false;
                 outputRelay.relay_event.bits.AC_Contactor = YES;
@@ -2143,6 +2315,9 @@ int main(void)
                 }
             }
 
+            if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+                outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
+
             // 搭上/鬆開 Relay
             if(IsNoneMatchRelayStatus())
             {
@@ -2171,54 +2346,21 @@ int main(void)
 
         if (ShmFanModuleData->SelfTest_Comp == YES)
         {
-            // 風控修改 :
-            // ******************************************************* //
-            //
-            //       當前PSU輸出總 KW       PSU Temp
-            // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
-            //       當前樁最大功率 KW         45
-            //
-            // ******************************************************* //
             if (GetTimeoutValue(_priority_time) / 1000 >= 1000)
             {
-                GetPsuTempForFanSpeed();
-
+                //GetPsuTempForFanSpeed();
+                GetFanSpeedByFunction();
                 GetFanSpeed();
                 ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
 
                 gettimeofday(&_priority_time, NULL);
-                if (isCharging)
-                {
-                    // 在還沒問到 PSU 溫度~ 還是要有個最小轉速
-                    ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
 
-                    if (ShmFanModuleData->TestFanSpeed > 0)
-                    {
-                        ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-                    }
-                }
-                else
-                {
-                    ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
+                ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+
 
-                    // 停止時,如溫度還是很高,則需要維持該轉速直到溫度降低
-                    if (ShmFanModuleData->TestFanSpeed >= MAX_FAN_SPEED)
-                    {
-                        ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-                    }
-                }
 
                 //PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
                 SetFanModuleSpeed();

+ 34 - 22
EVSE/Projects/DM30/Apps/Module_LcmControl.c

@@ -888,10 +888,7 @@ void ProcessPageInfo()
                 if (ShmSysConfigAndInfo->SysConfig.isQRCode)
                 {
                     needReloadQr = false;
-                    char QrCodeContent[128];
-                    strcpy(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
-                    strcat(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber);
-                    ChangeQrCode_Idle(QrCodeContent);
+                    ChangeQrCode_Idle((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
                 }
             }
         }
@@ -952,17 +949,20 @@ void ProcessPageInfo()
                     if (_currentPage == _LCM_CHARGING)
                     {
                         ChangeAcBattMapAndValue(_LCM_CHARGING);
-                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0)
+                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0 &&
+                            ac_chargingInfo[0]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(ac_chargingInfo[0]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                             ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
                         else
                             ChangeChargingEnergyValue(0);
@@ -975,17 +975,20 @@ void ProcessPageInfo()
                     else if (_currentPage == _LCM_COMPLETE)
                     {
                         ChangeAcBattMapAndValue(_LCM_COMPLETE);
-                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0)
+                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0 &&
+                            ac_chargingInfo[0]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(ac_chargingInfo[0]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1&&
+                            ac_chargingInfo[0]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                         {
                             ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
 
@@ -1066,17 +1069,20 @@ void ProcessPageInfo()
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                         ChangeBattMapAndValue(_LCM_CHARGING, _chargingInfoData[i]->EvBatterySoc);
-                        if (_chargingInfoData[i]->PresentChargedDuration >= 0)
+                        if (_chargingInfoData[i]->PresentChargedDuration >= 0 &&
+                            _chargingInfoData[i]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(_chargingInfoData[i]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (_chargingInfoData[i]->PresentChargingPower >= 0)
+                        if (_chargingInfoData[i]->PresentChargingPower >= 0 &&
+                            _chargingInfoData[i]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
+                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1 &&
+                            _chargingInfoData[i]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
                         else
                             ChangeChargingEnergyValue(0);
@@ -1092,17 +1098,20 @@ void ProcessPageInfo()
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                         ChangeBattMapAndValue(_LCM_COMPLETE, _chargingInfoData[i]->EvBatterySoc);
-                        if (_chargingInfoData[i]->PresentChargedDuration >= 0)
+                        if (_chargingInfoData[i]->PresentChargedDuration >= 0 &&
+                            _chargingInfoData[i]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(_chargingInfoData[i]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (_chargingInfoData[i]->PresentChargingPower >= 0)
+                        if (_chargingInfoData[i]->PresentChargingPower >= 0 &&
+                            _chargingInfoData[i]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
+                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1 &&
+                            _chargingInfoData[i]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                         {
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
 
@@ -1153,10 +1162,7 @@ void ProcessPageInfo()
                         if (ShmSysConfigAndInfo->SysConfig.isQRCode)
                         {
                             needReloadQr = false;
-                            char QrCodeContent[128];
-                            strcpy(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
-                            strcat(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber);
-                            ChangeQrCode_Charge(QrCodeContent);
+                            ChangeQrCode_Charge((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
                         }
                     }
                 }
@@ -1206,12 +1212,14 @@ void Initialization()
         {
             if (!FindChargingInfoData(_index, &_chargingInfoData[0]))
             {
-                DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
+                DEBUG_ERROR("LcmComm (main) : FindChargingInfoData false \n");
                 isPass = false;
                 count--;
                 break;
             }
         }
+
+        sleep(1);
     }
 
     isPass = false;
@@ -1225,11 +1233,13 @@ void Initialization()
             {
                 if (!FindAcChargingInfoData(_index, &ac_chargingInfo[0]))
                 {
-                    DEBUG_ERROR("EvComm : FindAcChargingInfoData false \n");
+                    DEBUG_ERROR("LcmComm : FindAcChargingInfoData false \n");
                     isPass = false;
                     break;
                 }
             }
+
+            sleep(1);
         }
     }
 
@@ -1261,6 +1271,8 @@ int main(void)
     Initialization();
 
     //return 0;
+    for(byte i = 0; i < 3; i++)
+        ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
 
     while(_port != -1)
     {

+ 4 - 0
EVSE/Projects/DM30/Apps/Module_LcmControl.h

@@ -44,6 +44,10 @@ struct FanModuleData            *ShmFanModuleData;
 #define NO_DEFINE           255
 #define DEFAULT_AC_INDEX    2
 
+#define TIME_MAX_SEC        2592000 // 一個月,秒數
+#define POWER_MAX_KW        5000
+#define ENERGY_MAX_KWH      5000
+
 #define CMD_TITLE_1             0x5A
 #define CMD_TITLE_2             0xA5
 #define CMD_READ                0x80

+ 2 - 1
EVSE/Projects/DM30/Apps/Module_PrimaryComm.c

@@ -439,7 +439,8 @@ int main(void)
         {
             if ((GetTimeoutValue(_flash_time) / 1000) > 5000)
             {
-                flash = YES;
+                if (flash == NO)
+                    flash = YES;
 
                 SetOutputGpio(flash);
                 gettimeofday(&_flash_time, NULL);

+ 251 - 136
EVSE/Projects/DM30/Apps/Module_PsuComm.c

@@ -348,14 +348,43 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     int _groupPower = 0, _groupCurrent = 0;
     byte group = FindTargetGroup(address);
+    float _chargingVol = 0, _targetVol = 0;
 
     if (group == 1)
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
 
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+    {
+        for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
+        {
+            if (chargingInfo[groupIndex]->EvBatteryMaxVoltage > 0)
+            {
+                _chargingVol = chargingInfo[groupIndex]->EvBatteryMaxVoltage;
+                _targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
+                break;
+            }
+        }
+    }
+
     if (chargingInfo[group]->DeratingChargingCurrent == 0)
-        ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+    {
+        // 在還沒取得真正可輸出的電流前,依照 GFD 階段得到的真正 POWER / 模塊個數 / 車子電池最大電壓
+        if (ShmPsuData->PsuGroup[group].GroupRealOutputPower > 0 && _chargingVol > 0)
+        {
+            ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent =
+                    ((ShmPsuData->PsuGroup[group].GroupRealOutputPower / ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity) * 1000 / (int)_chargingVol) * 10;
+        }
+        else
+        {
+            // 注一 : 獲取模塊最大輸出能力 (忽視 Derating 狀態),所以這邊需要限制實際可輸出的電流
+            if (ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent <= 0)
+                ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+        }
+    }
     else
+    {
         ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
+    }
 
     ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
     // 總和該 Group 的可輸出電流
@@ -371,7 +400,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     chargingInfo[group]->MaximumChargingVoltage = maxVol;
 
-    int _power = 0, _current = 0, _ratingcurrent = 0;
+    int _power = 0, _current = 0, _ratingcurrent = 0, _sysRealPower = 0;
     bool isGetAllDeratingCurrent = true;
 
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
@@ -379,6 +408,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
         _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
         _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
         _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent;
+        _sysRealPower += ShmPsuData->PsuGroup[index].GroupRealOutputPower;
         if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage >= PSU_MIN_VOL &&
             chargingInfo[index]->DeratingChargingCurrent == 0)
             isGetAllDeratingCurrent = false;
@@ -386,6 +416,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     // 如果不是所有群都得到 Derating current,則先不採樣該次的 ratingCurrent
     if (!isGetAllDeratingCurrent) _ratingcurrent = 0;
+    if (_ratingcurrent != 0) _current = _ratingcurrent;
 
     ShmPsuData->SystemAvailableCurrent = _current;
     ShmPsuData->SystemAvailablePower = _power;
@@ -397,6 +428,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
         int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
         int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
         int ratingCur = chargingInfo[group]->DeratingChargingCurrent;
+        int gpRealPow = ShmPsuData->PsuGroup[group].GroupRealOutputPower;
 
         if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
             ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
@@ -412,25 +444,24 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
         GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur);
 
-//      if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
-//               ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
-//      {
-//          chargingInfo[group]->AvailableChargingCurrent = DERATING_RANGE;
-//          chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
-//      }
-//      else
+
+        // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
+        // 1. 如不是最大充
+        // 2. 智能切換成均充過程
+        chargingInfo[group]->AvailableChargingCurrent = halfCur;
+        chargingInfo[group]->AvailableChargingPower = halfPow;
+        chargingInfo[group]->RealRatingPower = gpRealPow;
+
+        if(chargingInfo[group]->DeratingChargingCurrent > 0)
         {
-            // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
-            // 1. 如不是最大充
-            // 2. 智能切換成均充過程
-            chargingInfo[group]->AvailableChargingCurrent = halfCur;
-            chargingInfo[group]->AvailableChargingPower = halfPow;
+            unsigned short _powBuf = 0;
+            _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW
 
-            if(chargingInfo[group]->DeratingChargingCurrent > 0)
+            if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower ||
+                chargingInfo[group]->EvBatterytargetVoltage > 0)
             {
-                chargingInfo[group]->RealRatingPower = (chargingInfo[group]->DeratingChargingCurrent * chargingInfo[group]->PresentChargingVoltage) / 100000;
+                ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf;
             }
-            //printf("(Aver.) RealRatingPower = %d \n", chargingInfo[group]->RealRatingPower);
         }
     }
     else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
@@ -444,6 +475,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
                 chargingInfo[count]->MaximumChargingVoltage = maxVol;
                 chargingInfo[count]->AvailableChargingCurrent = _current;
                 chargingInfo[count]->AvailableChargingPower = _power;
+                chargingInfo[count]->RealRatingPower = _sysRealPower;
             }
         }
         else
@@ -451,13 +483,21 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
             // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
             chargingInfo[group]->AvailableChargingCurrent = _current;
             chargingInfo[group]->AvailableChargingPower = _power;
+            chargingInfo[group]->RealRatingPower = _sysRealPower;
         }
 
-        if(_ratingcurrent > 0)
+        if(chargingInfo[group]->DeratingChargingCurrent > 0)
         {
-            chargingInfo[group]->RealRatingPower = (_ratingcurrent * chargingInfo[group]->PresentChargingVoltage) / 100000;
+            unsigned short _powBuf = 0;
+            _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW
+
+            if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower ||
+                    chargingInfo[group]->EvBatterytargetVoltage > 0 ||
+                    _targetVol > 0)
+            {
+                ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf;
+            }
         }
-        //printf("(Max.) RealRatingPower = %d \n", chargingInfo[group]->RealRatingPower);
     }
 }
 
@@ -635,10 +675,11 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
     bool isPass = true;
     int totalCur = 0;
+    byte sampleCount = 8;
 
     if (Iavail == 0)
     {
-        for (byte count = 0; count < 2; count++)
+        for (byte count = 0; count < sampleCount; count++)
         {
             chargingInfo[group]->SampleChargingCur[count] = Iavail;
         }
@@ -651,7 +692,7 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
             totalCur += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
         }
 
-        for (byte count = 0; count < 2; count++)
+        for (byte count = 0; count < sampleCount; count++)
         {
             if (chargingInfo[group]->SampleChargingCur[count] == 0)
             {
@@ -672,106 +713,126 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
     if (isPass)
     {
-        //PRINTF_FUNC("rating pass value = %d \n", totalCur);
         chargingInfo[group]->DeratingChargingCurrent = totalCur;
     }
 }
 
-//==========================================
-// 特規用指令
-//==========================================
-void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
-                              unsigned short outputCur_s, unsigned short outputPower,
-                              unsigned char Temperature)
+void GetPresentOutputFCallback(byte group, float outVol, float outCur)
 {
-    if (ShmPsuData->Work_Step < GET_SYS_CAP)
-        return;
-
-    unsigned short outVol = outputVol_s;
-    unsigned short outCur = outputCur_s;
-
-    if (IsOverModuleCount(address))
-        return;
+    // isinf : -1 = 負無窮,1 = 正無窮,0 = 其他
+    if (isinf(outVol) == 0)
+        ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = (unsigned short)(outVol * 10);
+    else
+        ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = 0;
 
-    byte group = FindTargetGroup(address);
+    if (isinf(outCur) == 0)
+        ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = (unsigned short)(outCur * 10);
+    else
+        ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = 0;
 
-    if (group == 1)
-        address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
+                (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
+                (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING &&
+                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_COMP))
+            )
+        {
+            unsigned short outputVol = 0;
+            unsigned short outputCur = 0;
+            unsigned char _maxTOaver = 0;
 
-    // PSU Group - 電壓
-    ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outVol;
-    // PSU Group - 電流
-    ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outCur;
+            for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+            {
+                bool needtoAdd = true;
 
-    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
-        (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
-         (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING &&
-          ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_COMP)))
-    {
-        unsigned short outputVol = 0;
-        unsigned short outputCur = 0;
+                if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
+                    outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
 
-        for (byte index = 0; index < ShmPsuData->GroupCount; index++)
-        {
-            bool needtoAdd = true;
+                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A &&
+                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                {
+                    if (chargingInfo[index]->DividChargingCurrent == 0)
+                        needtoAdd = false;
+                    else
+                        _maxTOaver = index;
+                }
 
-            if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
-                outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
+                if (needtoAdd)
+                    outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
+            }
 
             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A &&
-                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
             {
-                if (chargingInfo[index]->DividChargingCurrent == 0)
-                    needtoAdd = false;
+                if (chargingInfo[_maxTOaver]->DividChargingCurrent != 0)
+                {
+                    float _cur_buf = outputCur;
+                    _cur_buf /= 10;
+                    chargingInfo[_maxTOaver]->PresentChargingCurrent = _cur_buf;
+                }
             }
 
-            if (needtoAdd)
-                outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
-        }
+            // 黑白機
+            if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
+            {
+                for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+                {
+                    float _vol_buf = outputVol;
+                    float _cur_buf = outputCur;
 
-        // 黑白機
-        if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
-        {
-            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+                    // EVSE - 電壓
+                    _vol_buf /= 10;
+                    chargingInfo[count]->PresentChargingVoltage = _vol_buf;
+
+                    _cur_buf /= 10;
+                    chargingInfo[count]->PresentChargingCurrent = _cur_buf;
+                }
+            }
+
+            if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
+                (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
             {
                 float _vol_buf = outputVol;
                 float _cur_buf = outputCur;
 
                 // EVSE - 電壓
                 _vol_buf /= 10;
-                chargingInfo[count]->PresentChargingVoltage = _vol_buf;
-                // EVSE - 電流
+                chargingInfo[group]->PresentChargingVoltage = _vol_buf;
+
                 _cur_buf /= 10;
-                chargingInfo[count]->PresentChargingCurrent = _cur_buf;
+                chargingInfo[group]->PresentChargingCurrent = _cur_buf;
             }
         }
-
-        if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
-            (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
+        else
         {
-            float _vol_buf = outputVol;
-            float _cur_buf = outputCur;
+            float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+            float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
 
             // EVSE - 電壓
             _vol_buf /= 10;
             chargingInfo[group]->PresentChargingVoltage = _vol_buf;
-            // EVSE - 電流
+
             _cur_buf /= 10;
             chargingInfo[group]->PresentChargingCurrent = _cur_buf;
         }
-    }
-    else
-    {
-        float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
-        float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
-
-        // EVSE - 電壓
-        _vol_buf /= 10;
-        chargingInfo[group]->PresentChargingVoltage = _vol_buf;
-        // EVSE - 電流
-        _cur_buf /= 10;
-        chargingInfo[group]->PresentChargingCurrent = _cur_buf;
-    }
+}
+
+//==========================================
+// 特規用指令
+//==========================================
+void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
+                              unsigned short outputCur_s, unsigned short outputPower,
+                              unsigned char Temperature)
+{
+    if (ShmPsuData->Work_Step < GET_SYS_CAP)
+        return;
+
+    if (IsOverModuleCount(address))
+        return;
+
+    byte group = FindTargetGroup(address);
+
+    if (group == 1)
+        address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
 
     ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp1 = Temperature;
     ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp2 = Temperature;
@@ -929,6 +990,7 @@ void Initialization()
                 break;
             }
         }
+        sleep(1);
     }
 
     if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
@@ -951,6 +1013,8 @@ void Initialization()
             count = 1;
         else if (strcmp(EvsePower, "60") == EQUAL)
             count = 2;
+        else if (strcmp(EvsePower, "12") == EQUAL)
+            count = 4;
         else if (strcmp(EvsePower, "18") == EQUAL)
             count = 6;
         else if (strcmp(EvsePower, "36") == EQUAL)
@@ -1072,6 +1136,7 @@ int main(void)
     RefreshGetOutput(&GetPresentOutputCallback);
     RefreshFanInfo(&GetFanSpeedCallback);
     RefreshIavailable(&GetIavailableCallback);
+    RefreshGetOutputF(&GetPresentOutputFCallback);
 
     // GetPresentOutputCallback & GetStatusCallback
     AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
@@ -1098,6 +1163,7 @@ int main(void)
             if (!isInitialComp)
             {
                 ShmPsuData->Work_Step = INITIAL_START;
+                sleep(2);
                 InitialPsuData();
                 isInitialComp = YES;
             }
@@ -1135,8 +1201,6 @@ int main(void)
 
                 if (time > 2000)
                 {
-                    PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
-                                ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 //                  if (ShmPsuData->GroupCount == 0)
 //                      ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
                     // 分別取各群模組數量
@@ -1148,6 +1212,8 @@ int main(void)
                         // 取各群模組數量
                         GetModuleCount(index);
                     }
+                    PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
+                                ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 
                     // 發送取得目前全部模組數量
                     GetModuleCount(SYSTEM_CMD);
@@ -1172,7 +1238,6 @@ int main(void)
                         }
                     }
 
-                    _getCapDelayCount = 7;
                     gettimeofday(&_cmdSubPriority_time, NULL);
                 }
             }
@@ -1183,30 +1248,42 @@ int main(void)
 
                 if (time > 1000)
                 {
-                    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                    bool isFinish = true;
+                    for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++)
                     {
-                        // Pooling Status
-                        //GetStatus(index);
+                        if (strcmp((char *)ShmPsuData->PsuVersion[psuCount].FwPrimaryVersion, "") == EQUAL ||
+                                ShmPsuData->SystemAvailablePower <= 0 || ShmPsuData->SystemAvailableCurrent <= 0)
+                        {
+                            isFinish = false;
+                            break;
+                        }
+                    }
 
-                        // 取系統總輸出能力
-                        GetModuleCap(index);
+                    if (!isFinish)
+                    {
+                        for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                        {
+                            // Pooling Status
+                            //GetStatus(index);
+
+                            // 取系統總輸出能力
+                            GetModuleCap(index);
 
-                        // 取版號
-                        GetModuleVer(index);
+                            // 取版號
+                            GetModuleVer(index);
+                        }
                     }
-                    _getCapDelayCount--;
-                    gettimeofday(&_cmdSubPriority_time, NULL);
-                }
+                    else
+                    {
+                        // 判斷系統輸出額定功率與電流
+                        PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
+                                    ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
 
-                // 判斷系統輸出額定功率與電流
-                if (ShmPsuData->SystemAvailablePower > 0 && ShmPsuData->SystemAvailableCurrent > 0 &&
-                    _getCapDelayCount <= 0)
-                {
-                    PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
-                                ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
+                        PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
+                        ShmPsuData->Work_Step = BOOTING_COMPLETE;
+                    }
 
-                    PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
-                    ShmPsuData->Work_Step = BOOTING_COMPLETE;
+                    gettimeofday(&_cmdSubPriority_time, NULL);
                 }
             }
                 break;
@@ -1240,12 +1317,6 @@ int main(void)
 
                     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
                     {
-                        // Pooling Status
-                        //GetStatus(index);
-
-                        // 取得模塊輸出額定電流能力
-                        GetModuleIavailable(index);
-
                         if (chargingInfo[index]->SystemStatus == S_CHARGING)
                         {
                             isCharging = true;
@@ -1298,30 +1369,33 @@ int main(void)
                     // 取系統總輸出能力
                     GetModuleCap(groupIndex);
 
+                    // 取各群輸出電壓電流 (float)
+                    GetModuleOutputF(groupIndex);
+
+                    // 取得模塊輸出額定電流能力
+                    GetModuleIavailable(groupIndex);
+
                     // 針對各槍當前狀態,傳送需要回傳的資料指令
                     if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
                         (chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING && chargingInfo[groupIndex]->Type == _Type_GB) ||
                         (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
                     {
-                        if (time > 1500)
+                        if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
+                        evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
                         {
-                            if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
-                                evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
-                            {
-                                evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
-                                PRINTF_FUNC("groupIndex = %d, ev need vol = %f, evse output vol = %f \n", groupIndex,
-                                            (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
-                                            chargingInfo[groupIndex]->FireChargingVoltage);
-                            }
+                            evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
+                            PRINTF_FUNC("groupIndex = %d, ev need vol = %f, evse output vol = %f \n", groupIndex,
+                                        (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
+                                        chargingInfo[groupIndex]->FireChargingVoltage);
+                        }
 
-                            if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
-                                evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
-                            {
-                                evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
-                                PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
-                                            (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
-                                            (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
-                            }
+                        if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
+                            evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
+                        {
+                            evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
+                            PRINTF_FUNC("groupIndex = %d, ev need cur = %f, evse output cur = %f \n", groupIndex,
+                                        (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
+                                        (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
                         }
 
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
@@ -1348,6 +1422,7 @@ int main(void)
                             else
                             {
                                 chargingInfo[groupIndex]->DividChargingCurrent = 0;
+                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 0;
                             }
 
                             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
@@ -1456,8 +1531,10 @@ int main(void)
 
                                         if (reassignIndex != ELEMENT_NOT_FIND)
                                         {
-                                            if ((GetTimeoutValue(_derating_time) / 1000) <= 50)
+                                            if ((GetTimeoutValue(_derating_time) / 1000) <= 50 ||
+                                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag == 0)
                                             {
+                                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 1;
                                                 // A 模塊維持當前電壓電流
                                                 //PRINTF_FUNC("A : index = %d, cur = %d \n", groupIndex, ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
                                                 //PresentOutputVol(groupIndex, targetVol, ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
@@ -1502,10 +1579,8 @@ int main(void)
                                                      (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
                                                      (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10));
                                 }
-                                else
+                                else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                                 {
-                                    PRINTF_FUNC("set out (sys) value = %f, smart step = %d******** 4 \n",
-                                                chargingInfo[groupIndex]->EvBatterytargetCurrent, ShmSysConfigAndInfo->SysInfo.ReAssignedFlag);
                                     // 該充電槍的目標電壓與目標電流
                                     PresentOutputVol(SYSTEM_CMD,
                                                      (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
@@ -1852,6 +1927,46 @@ int main(void)
                 }
                     break;
             }
+            case _TEST_MODE:
+            {
+                // 在測試模式中,保持與模塊的通訊
+                int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
+
+                if (time > 1500)
+                {
+                    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                    {
+                        // 取系統總輸出能力
+                        GetModuleCap(index);
+
+                        // 取各群輸出電壓電流 (float)
+                        GetModuleOutputF(index);
+                    }
+
+                    gettimeofday(&_cmdSubPriority_time, NULL);
+                }
+
+                byte _switch = 0x00;
+                if ((chargingInfo[0]->EvBatterytargetVoltage * 10) > 0 && (chargingInfo[0]->EvBatterytargetCurrent * 10) > 0)
+                    _switch = 0x01;
+
+                for (byte _groupCount_1 = 0; _groupCount_1 < conn_1_count; _groupCount_1++)
+                {
+                    SetDirModulePresentOutput(connector_1[_groupCount_1],
+                        (chargingInfo[0]->EvBatterytargetVoltage * 10),
+                        (chargingInfo[0]->EvBatterytargetCurrent * 10),
+                        _switch, _switch);
+                }
+
+                for (byte _groupCount_2 = 0; _groupCount_2 < conn_2_count; _groupCount_2++)
+                {
+                    SetDirModulePresentOutput(connector_2[_groupCount_2],
+                        (chargingInfo[0]->EvBatterytargetVoltage * 10),
+                        (chargingInfo[0]->EvBatterytargetCurrent * 10),
+                        _switch, _switch);
+                }
+            }
+                break;
         }
         usleep(20000);
     }

+ 0 - 1
EVSE/Projects/DM30/Apps/Module_PsuComm.h

@@ -41,7 +41,6 @@ struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANT
 bool isStartOutputSwitch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 struct timeval _cmdSubPriority_time;
-byte _getCapDelayCount;
 struct timeval _derating_time;
 struct timeval _max_time;
 

+ 373 - 0
EVSE/Projects/DM30/Apps/OutputTask.c

@@ -0,0 +1,373 @@
+/*
+ * OutputTask.c
+ *
+ *  Created on: 2020年2月25日
+ *      Author: 7564
+ */
+
+#include    "OutputTask.h"
+
+bool isOpen;
+
+int InitComPort()
+{
+    int fd;
+    struct termios tios;
+
+    fd = open(priPortName, O_RDWR);
+    if(fd<=0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("open 407 Communication port NG \n");
+        #endif
+        return -1;
+    }
+    ioctl (fd, TCGETS, &tios);
+    tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
+    tios.c_lflag = 0;
+    tios.c_iflag = 0;
+    tios.c_oflag = 0;
+    tios.c_cc[VMIN]=0;
+    tios.c_cc[VTIME]=(unsigned char)1;
+    tios.c_lflag=0;
+    tcflush(fd, TCIFLUSH);
+    ioctl (fd, TCSETS, &tios);
+
+    return fd;
+}
+
+unsigned long GetTimeoutValue(struct timeval _sour_time)
+{
+    struct timeval _end_time;
+    gettimeofday(&_end_time, NULL);
+
+    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+}
+
+void ShowMainMsg()
+{
+    printf("Max Vol : %f, Max Cur : %d, POW : %d \n", UnSafeDataInfo->PSU_VOLTAGE,
+            UnSafeDataInfo->PSU_CURRENT, UnSafeDataInfo->PSU_POWER);
+    printf("=> ");
+}
+
+void ChkButtonStatus()
+{
+    if (Button1 == PRESS && !leftBtnPush)
+    {
+        if(!leftBtnPush)
+        {
+            leftBtnPush = true;
+            if (_charging_mode == CHARGING_MODE_STOP)
+            {
+                _charging_mode = CHARGING_MODE_START;
+                printf("****************** Switch to Charging Mode ******************\n");
+            }
+        }
+        else if (Button1 == RELEASE)
+        {
+            if(leftBtnPush)
+            {
+                leftBtnPush = false;
+            }
+        }
+    }
+
+    if (Button2 == PRESS && !rightBtnPush)
+    {
+        if(!rightBtnPush)
+        {
+            rightBtnPush = true;
+            if (_charging_mode == CHARGING_MODE_START)
+            {
+                _charging_mode = CHARGING_MODE_TERMINATING;
+                printf("****************** Switch to Stop Mode ******************\n");
+            }
+        }
+        else if (Button2 == RELEASE)
+        {
+            if(rightBtnPush)
+            {
+                rightBtnPush = false;
+            }
+        }
+    }
+}
+
+void GetModuleCountCallback(byte group, byte count)
+{
+    printf("group = %d, count = %d \n", group, count);
+    if (group == SYSTEM_CMD)
+        UnSafeDataInfo->PSU_COUNT = count;
+}
+
+void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow)
+{
+    int _groupPower = 0, _groupCurrent = 0;
+
+    UnSafeDataInfo->PsuModule[address].PSU_VOLTAGE_INFO = maxVol;
+    UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO = maxCur;
+    UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO = totalPow;
+
+    for (byte index = 0; index < UnSafeDataInfo->PSU_COUNT; index++)
+    {
+        _groupCurrent += UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO;
+        _groupPower += UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO;
+    }
+
+    UnSafeDataInfo->PSU_VOLTAGE = maxVol;
+    UnSafeDataInfo->PSU_CURRENT = _groupCurrent;
+    UnSafeDataInfo->PSU_POWER = _groupPower;
+}
+
+void GetStatusCallback(byte group, byte address, byte temp, int alarm)
+{
+    printf("alarm = %d \n", alarm);
+}
+
+void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
+{
+    printf("vol1 = %d, vol2 = %d, vol3 = %d \n", vol1, vol2, vol3);
+}
+
+int CreateShareMemory()
+{
+    int MeterSMId;
+
+    if ((MeterSMId = shmget(ShmTestKey, sizeof(struct UnSafeData), IPC_CREAT | 0777)) < 0)
+    {
+        return 0;
+    }
+    else if ((UnSafeDataInfo = shmat(MeterSMId, NULL, 0))   == (void *) -1)
+    {
+        return 0;
+    }
+    memset(UnSafeDataInfo, 0, sizeof(struct UnSafeData));
+
+    return 1;
+}
+
+static void get_char(char *word)
+{
+    fd_set rfds;
+    struct timeval tv;
+
+    FD_ZERO(&rfds);
+    FD_SET(0, &rfds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 10; //wait input timout time
+
+    //if input
+    if (select(1, &rfds, NULL, NULL, &tv) > 0)
+    {
+        fgets(word, 128, stdin);
+    }
+}
+
+void GetInputString()
+{
+    char word[128];
+    char newString[7][10];
+    int i, j, ctr;
+
+    get_char(word);
+
+    if (strlen(word) == 0)
+        return;
+    //fgets(word, sizeof(word), stdin);
+
+    j = 0;
+    ctr = 0;
+    for (i = 0; i <= (strlen(word)); i++) {
+        if (word[i] == ' ' || word[i] == '\0' || word[i] == 10) {
+            newString[ctr][j] = '\0';
+            ctr++;
+            j = 0;
+        } else {
+            newString[ctr][j] = word[i];
+            j++;
+        }
+    }
+
+    VOLTAGE = atof(newString[0]);
+    CURRENT = atof(newString[1]);
+    if (VOLTAGE <= UnSafeDataInfo->PSU_VOLTAGE && CURRENT <= UnSafeDataInfo->PSU_CURRENT)
+    {
+        //printf("OutputVol = %f, OutputCur = %f \n", VOLTAGE, CURRENT);
+    }
+    else
+    {
+        ShowMainMsg();
+    }
+}
+
+void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
+{
+    //printf("address = %d, Iavail = %d, Vext = %d \n", address, Iavail, Vext);
+}
+
+void GetOutputAndTempCallback(byte address, unsigned short outputVol,
+        unsigned short outputCur, unsigned short outputPower, unsigned char Temperature)
+{
+    //printf("***Output Value and Temp*** address = %d, Vol = %d, Cur = %d, Pow = %d, Temp = %d \n",
+    //      address, outputVol, outputCur, outputPower, Temperature);
+}
+
+void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
+        unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
+{
+    //int alarm = (err2 << 24) | (err3 << 16) | (err4 << 8);
+
+    // err2 == state 2
+    // err3 == state 1
+    // err4 == state 0
+    //printf("***Status*** address = %d, alarm = %d \n", address, alarm);
+//  printf("***Status*** address = %d, err1 = %d, err2 = %d, err3 = %d, err4 = %d \n",
+//          address, err1,err2,err3,err4);
+}
+
+void GetModuleInputCallback(byte address, unsigned short inputR,
+        unsigned short inputS, unsigned short inputT)
+{
+
+}
+
+int main(void)
+{
+    isOpen =false;
+
+    if(CreateShareMemory() == 0)
+    {
+        printf("CreateShareMemory fail. \n");
+        return 0;
+    }
+    RefreshModuleCount(&GetModuleCountCallback);
+    RefreshAvailableCap(&GetAvailableCapCallback);
+
+    RefreshStatus(&GetStatusCallback);
+    RefreshInputVol(&GetInputVoltageCallback);
+
+    RefreshIavailable(&GetIavailableCallback);
+
+    AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
+    AutoMode_RefreshModuleStatus(&GetModuleStatusCallback);
+    AutoMode_RefreshModuleInput(&GetModuleInputCallback);
+
+    Uart1Fd = InitComPort();
+    libInitialize = InitialCommunication();
+
+    if (Uart1Fd < 0 || !libInitialize)
+    {
+        printf("Initial port fail. \n");
+        return 0;
+    }
+
+    sleep(5);
+    gettimeofday(&_cmdSubPriority_time, NULL);
+    VOLTAGE = 0.0;
+    CURRENT = 0.0;
+
+    SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+//  while (1)
+//  {
+//      printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
+//      SetWalkInConfig(0, YES, 0);
+//      SetWalkInConfig(1, NO, 0);
+//      printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+//      sleep(1);
+//  }
+//
+//  sleep(1);
+//      printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
+//      SetWalkInConfig(SYSTEM_CMD, NO, 0);
+//      printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+//  return 0;
+    while (1)
+    {
+        GetInputGpioStatus();
+        //ChkButtonStatus();
+        // 切換 Walk-in mode (default 5s -> 2s)
+        SetWalkInConfig(SYSTEM_CMD, NO, 0);
+
+        int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
+        while(isGetCount == YES)
+        {
+            if (_charging_mode == CHARGING_MODE_START)
+            {
+                // 取得模塊輸出額定電流能力
+                GetModuleIavailable(0);
+            }
+
+            GetInputString();
+            if (VOLTAGE > 150 && CURRENT >= 0)
+                _charging_mode = CHARGING_MODE_START;
+            else
+                _charging_mode = CHARGING_MODE_TERMINATING;
+            //printf("_charging_mode = %d \n", _charging_mode);
+            switch(_charging_mode)
+            {
+                case CHARGING_MODE_START:
+                {
+                    //if (!isOpen)
+                    {
+                        //SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
+                        //FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
+                        SetDirModulePresentOutput(0,
+                                                VOLTAGE * 10,
+                                                CURRENT * 10,
+                                                0x01,
+                                                0x01);
+                    }
+                    //PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10);
+                }
+                    break;
+                case CHARGING_MODE_TERMINATING:
+                {
+                    //if (isOpen)
+                    {
+                        SetDirModulePresentOutput(0,
+                            VOLTAGE * 10,
+                            CURRENT * 10,
+                            0x00,
+                            0x01);
+                        //SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+                        //FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+                    }
+                }
+                    break;
+            }
+            //GetStatus(0);
+            //GetModuleInput(0);
+            sleep(1);
+        }
+
+        if (UnSafeDataInfo->PSU_COUNT <= 0)
+        {
+            if (time > 1000)
+            {
+                printf("Step 1 : GetModuleCount...... \n");
+                GetModuleCount(SYSTEM_CMD);
+                gettimeofday(&_cmdSubPriority_time, NULL);
+            }
+        }
+        else if (time < 5000)
+        {
+            printf("Step 2 : GetModuleCap...... \n");
+            GetModuleCap(0);
+
+            SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+            FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+        }
+        else
+        {
+            ShowMainMsg();
+            isGetCount = YES;
+        }
+
+        sleep(1);
+    }
+
+    return 0;
+}
+
+

+ 174 - 0
EVSE/Projects/DM30/Apps/OutputTask.h

@@ -0,0 +1,174 @@
+/*
+ * OutputTask.h
+ *
+ *  Created on: 2020ฆ~2ค๋25ค้
+ *      Author: 7564
+ */
+
+#ifndef OUTPUTTASK_H_
+#define OUTPUTTASK_H_
+
+
+#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    <linux/can.h>
+#include    <linux/can/raw.h>
+#include    <arpa/inet.h>
+#include    <netinet/in.h>
+
+#include    <unistd.h>
+#include    <stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include    <errno.h>
+#include    <string.h>
+#include    <time.h>
+#include    <ctype.h>
+#include    <ifaddrs.h>
+#include    <stdbool.h>
+
+#define ShmTestKey  2001
+
+#define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
+#define PASS                1
+#define FAIL                -1
+#define YES                 1
+#define NO                  0
+#define PRESS               1
+#define RELEASE             0
+#define MAX_PSU_QUANTITY        62
+
+int Uart1Fd = -1;
+char *priPortName = "/dev/ttyS1";
+
+bool libInitialize = false;
+struct timeval _cmdSubPriority_time;
+
+unsigned char Button1 = RELEASE;
+unsigned char Button2 = RELEASE;
+bool leftBtnPush = false;
+bool rightBtnPush = false;
+
+unsigned char _psuCount = 0;
+unsigned char isGetCount = NO;
+
+float VOLTAGE;
+float CURRENT;
+
+struct PsuModuleInfo
+{
+    unsigned int    PSU_POWER_INFO;
+    float           PSU_VOLTAGE_INFO;
+    unsigned short  PSU_CURRENT_INFO;
+};
+
+struct UnSafeData
+{
+    unsigned char           PSU_COUNT;
+    struct PsuModuleInfo    PsuModule[MAX_PSU_QUANTITY];
+    unsigned int            PSU_POWER;
+    float                   PSU_VOLTAGE;
+    unsigned short          PSU_CURRENT;
+};
+
+struct UnSafeData           *UnSafeDataInfo;
+
+typedef struct GPIO_IN
+{
+    unsigned char AC_Connector;
+    unsigned char AC_MainBreaker;
+    unsigned char SPD;
+    unsigned char Door_Open;
+    unsigned char GFD[2];
+    unsigned char AC_Drop;
+    unsigned char Emergency_IO;
+
+    unsigned char Emergency_Btn;
+    unsigned char Button[2];
+    unsigned char Key[4];
+}Gpio_in;
+
+Gpio_in gpio_in;
+
+enum CHARGING_MODE
+{
+    CHARGING_MODE_STOP =            0x00,
+    CHARGING_MODE_START =           0x01,
+    CHARGING_MODE_TERMINATING =     0x10,
+};
+
+unsigned char _charging_mode = CHARGING_MODE_STOP;
+
+int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
+{
+    int len;
+    tcflush(fd,TCIOFLUSH);
+    if(write(fd, cmd, cmd_len) >= cmd_len)
+    {
+        usleep(50000);
+        len = read(fd, rx, 512);
+    }
+    else
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("Serial command %s response fail.\n", cmd);
+        #endif
+    }
+
+    return len;
+}
+
+unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, 0x0a, 0x00, 0x00, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 0)
+    {
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            Ret_Buf->Button[0]          = (rx[7] >> 1) & 0x01;
+            Ret_Buf->Button[1]          = (rx[7] >> 2) & 0x01;
+
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+void GetInputGpioStatus()
+{
+    if (Query_Gpio_Input(Uart1Fd, 0x04, &gpio_in) == PASS)
+    {
+        Button1 = gpio_in.Button[0];
+        Button2 = gpio_in.Button[1];
+    }
+}
+
+#endif /* OUTPUTTASK_H_ */

+ 188 - 20
EVSE/Projects/DM30/Apps/ReadCmdline.c

@@ -40,14 +40,26 @@
 typedef unsigned char           byte;
 #define PASS                1
 #define FAIL                -1
+#define EQUAL               0
 #define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
 #define NO_DEFINE           255
 #define DEFAULT_AC_INDEX    2
 
+#define AUTORUN_STEP1_TIME_START            140             // Minutes
+#define AUTORUN_STEP1_TIME_END              150
+#define AUTORUN_STEP2_TIME_START            210
+#define AUTORUN_STEP2_TIME_END              410
+#define AUTORUN_END_TIME                    480
+#define AUTORUN_CYCLE_COUNT                 30
+
 #define TTY_PATH            "/dev/tty"
 #define STTY_US             "stty raw -echo -F "
 #define STTY_DEF            "stty -raw echo -F "
 
+byte _curAutoRunCount = 0;
+byte _usingAutoRun = 0;
+struct timeval _autoTime;
+
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct PrimaryMcuData           *ShmPrimaryMcuData;
@@ -165,7 +177,8 @@ int InitShareMemory()
         else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
         {
             result = FAIL;
-        } else
+        }
+        else
         {
             //NULL
         }
@@ -237,11 +250,13 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
     struct timeval _end_time;
     gettimeofday(&_end_time, NULL);
 
-    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+    return (_end_time.tv_sec - _sour_time.tv_sec);
 }
 
 void RunStatusProc(char *v1, char *v2)
 {
+    printf("OrderCharging = %d \n", ShmSysConfigAndInfo->SysInfo.OrderCharging);
+    printf("WaitForPlugit = %d \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
     if (strcmp(v1, "ac") == 0)
     {
         if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
@@ -320,6 +335,26 @@ void RunCardProc(char *v1, char *v2)
 
 void RunGunPlugitProc(char *v1, char *v2)
 {
+    if (strcmp(v1, "ac") == 0)
+    {
+        if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
+        {
+            printf("FindChargingInfoData (AC) false \n");
+        }
+
+        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
+        {
+            // get
+            printf("ConnectorPlugIn = %d \n", ac_chargingInfo[0]->ConnectorPlugIn);
+        }
+        else
+        {
+            // set
+            ac_chargingInfo[0]->ConnectorPlugIn = atoi(v2);
+        }
+        return;
+    }
+
     int _index = atoi(v1);
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     {
@@ -411,7 +446,7 @@ void CreateOneError(char *v1)
 {
     int value = atoi(v1);
 
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = value;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = value;
     ShmSysConfigAndInfo->SysConfig.BillingData.isBilling = value;
 }
 
@@ -423,16 +458,17 @@ void GetAuthorizeFlag(char *v1)
         ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = atoi(v1);
 }
 
-void GetOrClearId(char *v1)
+void GetRelayStatus(char *v1)
 {
     int _index = atoi(v1);
-
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     {
         printf("FindChargingInfoData error\n");
         return;
     }
-    printf("Card Number = %s \n", _chargingData[_index]->StartUserId);
+
+    printf("RelayK1K2Status = %d \n", _chargingData[_index]->RelayK1K2Status);
+    printf("RelayKPK2Status = %d \n", _chargingData[_index]->RelayKPK2Status);
 }
 
 void FwUpdateFlagProc()
@@ -460,6 +496,19 @@ void SetCableChkStatus(char *v1, char *v2)
     _chargingData[_index]->GroundFaultStatus = atoi(v2);
 }
 
+void SetChargingInfoCCID(char *v1, char* v2)
+{
+    int _index = atoi(v1);
+    if (!FindChargingInfoData(_index, &_chargingData[0]))
+    {
+        printf ("FindChargingInfoData error\n");
+        return;
+    }
+
+    memcpy(_chargingData[_index]->EVCCID, v2, 8);
+    _chargingData[_index]->EVCCID[8] = '\0';
+}
+
 void SetPowerValue(char *v1, char *v2)
 {
     int _index = atoi(v1);
@@ -582,7 +631,7 @@ void GetAcInputVol()
            ShmSysConfigAndInfo->SysInfo.InputVoltageT);
 }
 
-void GetPsuInformation(char *v1)
+void GetPsuInformation(char *v1, char *v2, char *v3)
 {
     printf("**********************AC Contact needed*************************\n");
     if(strcmp(v1, "count") == 0)
@@ -617,6 +666,20 @@ void GetPsuInformation(char *v1)
                    i, ShmPsuData->PsuGroup[i].GroupAvailableCurrent, ShmPsuData->PsuGroup[i].GroupAvailablePower);
         }
     }
+    else if(strcmp(v1, "input") == 0)
+    {
+        for (int i = 0; i < ShmPsuData->GroupCount; i++)
+        {
+            for (byte count = 0; count < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; count++)
+            {
+                printf("gp = %d, Index = %d, volR = %d, volS = %d, volT = %d \n",
+                       i, count,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL1,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL2,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL3);
+            }
+        }
+    }
     else if (strcmp(v1, "output") == 0)
     {
         for (int i = 0; i < ShmPsuData->GroupCount; i++)
@@ -624,6 +687,43 @@ void GetPsuInformation(char *v1)
             printf("Group Index = %d, OutputV = %d, OutputC = %d \n",
                    i, ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage, ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent);
         }
+
+        for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++)
+        {
+            if (!FindChargingInfoData(i, &_chargingData[0]))
+            {
+                printf ("FindChargingInfoData error\n");
+                continue;
+            }
+
+            printf("Form RB : Group Index = %d, OutputV = %f \n",
+                i, _chargingData[i]->FireChargingVoltage);
+        }
+    }
+    else if (strcmp(v1, "test") == 0)
+    {
+        int mode = atoi(v2);
+
+        if (mode >= _TEST_MODE && mode <= _TEST_MODE)
+        {
+            ShmPsuData->Work_Step = mode;
+        }
+    }
+    else if (strcmp(v1, "out") == 0)
+    {
+        float vol = atof(v2);
+        float cur = atof(v3);
+
+        if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+        {
+            if (!FindChargingInfoData(0, &_chargingData[0]))
+            {
+                printf ("FindChargingInfoData error\n");
+                return;
+            }
+            _chargingData[0]->EvBatterytargetVoltage = vol;
+            _chargingData[0]->EvBatterytargetCurrent = cur;
+        }
     }
     printf("*************************************************\n");
 }
@@ -668,18 +768,34 @@ static void get_char(char *word)
 
 void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 {
-    int _GunIndex = atoi(v1);
-    float _Voltage = atof(v2);
-    float _Current = atof(v3);
-    unsigned char PreviousSystemStatus = 0xff;
+    int _GunIndex;
+    float _Voltage;
+    float _Current;
 
+    if (strcmp(v1, "auto") == EQUAL)
+    {
+        _usingAutoRun = 0x01;
+        _GunIndex = 0;
+        _Voltage = 500;
+        _Current = (ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 1000) / _Voltage;
+    }
+    else
+    {
+        _usingAutoRun = 0x00;
+        _GunIndex = atoi(v1);
+        _Voltage = atof(v2);
+        _Current = atof(v3);
+    }
+
+    unsigned char PreviousSystemStatus = 0xff;
     if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
     {
         printf ("FindChargingInfoData error\n");
         return;
     }
 
-    printf ("ReqVoltage = %f, ReqCurrent = %f\n", _Voltage, _Current);
+    printf ("Power = %d, ReqVoltage = %f, ReqCurrent = %f\n",
+            ShmSysConfigAndInfo->SysConfig.MaxChargingPower, _Voltage, _Current);
 
     if(_Voltage > 1000 || _Voltage < 50)
     {
@@ -841,15 +957,50 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 {
                     PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
 
-                    //充電電壓電流
+                    if (_usingAutoRun == 0x00)
+                    {
+                        //充電電壓電流
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
+                    }
+                    else
+                    {
+                        _curAutoRunCount = 0;
+                        gettimeofday(&_autoTime, NULL);
+                    }
+
                     _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
-                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
-                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
                     _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;
 
                     printf ("[UnconditionalCharge - S_CHARGING]\n");
                 }
 
+                if (_usingAutoRun == 0x01)
+                {
+                    if (((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP1_TIME_START * 60 && (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP1_TIME_END * 60) ||
+                        ((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP2_TIME_START * 60 && (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP2_TIME_END * 60))
+                    {
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
+                    }
+                    else if ((GetTimeoutValue(_autoTime)) >= AUTORUN_END_TIME * 60)
+                    {
+                        _curAutoRunCount++;
+                        if (_curAutoRunCount >= AUTORUN_CYCLE_COUNT)
+                            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+                        else
+                            gettimeofday(&_autoTime, NULL);
+                    }
+                    else
+                    {
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 0;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 0;
+                    }
+                }
+
+//              printf("out : vol = %f, cur = %f \n",
+//                      _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage,
+//                      _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent);
                 //ev task do this
                 _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower =
                         ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent)) / 1000);
@@ -888,6 +1039,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
                     printf ("[UnconditionalCharge - S_COMPLETE]\n");
                 }
+
+                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = 0;
                 sleep(3);
                 return;
             }
@@ -1113,7 +1266,7 @@ int main(void)
             }
 
             // 取得 PSU 資訊
-            GetPsuInformation(newString[1]);
+            GetPsuInformation(newString[1], newString[2], newString[3]);
         }
         else if (strcmp(newString[0], "cap") == 0)
         {
@@ -1127,15 +1280,30 @@ int main(void)
         {
             GetAuthorizeFlag(newString[1]);
         }
-        else if (strcmp(newString[0], "id") == 0)
+        else if (strcmp(newString[0], "relay") == 0)
         {
-            GetOrClearId(newString[1]);
+            GetRelayStatus(newString[1]);
         }
-        else if(strcmp(newString[0], "strchg") == 0)
+        else if (strcmp(newString[0], "ccid") == 0)
         {
-            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
                 strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
+            {
+                printf ("Input ccid fail.\n");
+                continue;
+            }
+            SetChargingInfoCCID(newString[1], newString[2]);
+        }
+        else if(strcmp(newString[0], "strchg") == 0)
+        {
+            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
+            if (strcmp(newString[1], "auto") == 0)
+            {
+                newString[2][0] = 0;
+                newString[3][0] = 0;
+            }
+            else if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
+                     strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
             {
                 printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
                 continue;

File diff suppressed because it is too large
+ 363 - 153
EVSE/Projects/DM30/Apps/main.c


+ 1 - 0
EVSE/Projects/DM30/Apps/timeout.h

@@ -58,4 +58,5 @@ unsigned short _connectionTimeout;
 
 // for main
 struct timeval _cmdMainPriority_time;
+struct timeval _toAverage_time;
 #endif /* TIMEOUT_H_ */

+ 20 - 2
EVSE/Projects/DW30/Apps/Config.h

@@ -30,7 +30,7 @@ typedef unsigned char           byte;
 #define MODE_DEBUG                  16
 #define MODE_CCS_PRECHARGE_STEP0    17  // ready for ccs precharge processing, For D+ relay to precharge relay
 #define MODE_CCS_PRECHARGE_STEP1    18  // waitting for ev board inform to enter to charging, For precharge relay to D+ relay
-#define MODE_SINGLE_RUN             19
+#define MODE_UPDATE                 19
 
 #define GFD_WAIT                    0
 #define GFD_PASS                    1
@@ -66,7 +66,7 @@ enum _SYSTEM_STATUS
     S_DEBUG                             = 16,
     S_CCS_PRECHARGE_ST0                 = 17,
     S_CCS_PRECHARGE_ST1                 = 18,
-    S_SINGLE_RUN                        = 19,
+    S_UPDATE                            = 19,
     S_NONE                              = 20,
 };
 
@@ -119,7 +119,11 @@ enum _MODULE_PSU_WORK_STEP
     GET_PSU_COUNT                       = 1,
     GET_SYS_CAP                         = 2,
     BOOTING_COMPLETE                    = 3,
+
     _WORK_CHARGING                      = 10,
+
+    _TEST_MODE                          = 20,
+
     _NO_WORKING                         = 254,
     _INIT_PSU_STATUS                    = 255,
 };
@@ -174,4 +178,18 @@ enum _SYS_WIFI_MODE
     _SYS_WIFI_MODE_ADHOC                = 3,
 };
 
+enum _LED_INTENSITY_LV
+{
+    _LED_INTENSITY_DARKEST              = 0,
+    _LED_INTENSITY_MEDIUM               = 1,
+    _LED_INTENSITY_BRIGHTEST            = 2,
+};
+
+enum _CCS_COMM_PROTOCOL
+{
+    _CCS_COMM_V2GMessage_DIN70121       = 0x01,
+    _CCS_COMM_V2GMessage_ISO15118_2014  = 0x02,
+    _CCS_COMM_V2GMessage_ISO15118_2018  = 0x03,
+};
+
 #endif /* CONFIG_H_ */

+ 7 - 3
EVSE/Projects/DW30/Apps/FactoryConfig.c

@@ -106,7 +106,7 @@ int main(int argc,char *argv[])
     //********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
     //
     strcpy((char *)SysConfig.ModelName, "DWWU301U00W1PH");
-    strcpy((char *)SysConfig.SerialNumber, "");
+    strcpy((char *)SysConfig.SerialNumber, "NeedSetupSN");
 
     memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
     char Dash = '-';
@@ -130,7 +130,7 @@ int main(int argc,char *argv[])
     SysConfig.isRFID = 1;
     //********** Charging **********//
     SysConfig.MaxChargingEnergy = 0;
-    SysConfig.MaxChargingCurrent = 60;      // 最大可輸出電流
+    SysConfig.MaxChargingCurrent = 60;      // 最大可輸出電流 (整樁)
     SysConfig.MaxChargingDuration = 0;
     SysConfig.AcMaxChargingCurrent = 0;
     SysConfig.PhaseLossPolicy = LOSS_POLICY_STOP;
@@ -148,7 +148,10 @@ int main(int argc,char *argv[])
     strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
     strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
     strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
-    SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_AP;
+    if(SysConfig.ModelName[10] == 'W')
+        SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_AP;
+    else
+        SysConfig.AthInterface.WifiMode = _SYS_WIFI_MODE_DISABLE;
     strcpy((char *) SysConfig.AthInterface.WifiSsid, "");
     strcpy((char *) SysConfig.AthInterface.WifiPassword, "");
     SysConfig.AthInterface.WifiRssi = 0;
@@ -183,6 +186,7 @@ int main(int argc,char *argv[])
     //strcpy((char *) SysConfig.ChargeBoxId, "DemoDC");
     strcpy((char *) SysConfig.OcppServerURL, "");
     strcpy((char *) SysConfig.ChargeBoxId, "");
+    SysConfig.LedInfo.Intensity = 2;
 
     //copy default configuration to pointer
     memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));

+ 10 - 3
EVSE/Projects/DW30/Apps/Makefile

@@ -2,19 +2,20 @@
 export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)/usr/bin:$PATH
 
 #define library variable
-Internal485ProtocolLib = -L ../../../Modularization/Internal485Protocol -lInternal485Protocol
+Lib_Module_RFID = "-L../../../Modularization" -lModule_RFID
+Lib_Module_Upgrade = "-L../../../Modularization" -lModule_Upgrade
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
 all: CreateOutputFolder BuildFactorys BuildApps CopyExecuteFiles Clean
 
 BuildFactorys: FactoryConfigBin
 
-BuildApps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask FactoryConfigApp
+BuildApps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask FactoryConfigApp UnsafetyOutputTool
 
 MainTask:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -include../../../Modularization/ocppfiles/sqlite3.h -include../../../Modularization/Module_RFID.h -include../../../Modularization/Module_Upgrade.h -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.c
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -O0 -g3 -Wall -c -fmessage-length=0 -o timeout.o timeout.c
-	$(CC) -o main main.o timeout.o ../../../Modularization/libModule_RFID.a ../../../Modularization/libModule_Upgrade.a ${Lib_SQLite3}
+	$(CC) -o main main.o timeout.o ${Lib_Module_RFID} ${Lib_Module_Upgrade} ${Lib_SQLite3}
 
 EvCommTask:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Ev_Comm.o Ev_Comm.c
@@ -51,6 +52,10 @@ FactoryConfigApp:
 	$(CC) -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) -O0 -g3 -Wall -c -fmessage-length=0 -o FactoryConfig.o FactoryConfig.c
 	$(CC) -o FactoryConfig FactoryConfig.o
 
+UnsafetyOutputTool:
+	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -O0 -g3 -Wall -c -fmessage-length=0 -o OutputTask.o OutputTask.c
+	$(CC) -o UnsafetyOutputTask OutputTask.o ../../../Modularization/libInfypwr_PsuCommObj.a
+
 FactoryConfigBin:
 	gcc -D $(Project) -D DEBUG_OPTION=$(Project_Debug_Option) "-I../../" -o FactoryConfig "./FactoryConfig.c"
 	mkdir -p /Storage/SystemLog
@@ -76,6 +81,7 @@ CopyExecuteFiles: OtherTools
 	cp -f Module_PsuComm ../Images/root
 	cp -f ReadCmdline ../Images/root
 	cp -f FactoryConfig ../Images/root
+	cp -f UnsafetyOutputTask ../Images/root
 
 Clean: CleanObj CleanExecute
 
@@ -92,3 +98,4 @@ CleanExecute:
 	rm -f Module_PsuComm
 	rm -f ReadCmdline
 	rm -f FactoryConfig
+	rm -f UnsafetyOutputTask

+ 82 - 29
EVSE/Projects/DW30/Apps/Module_EvComm.c

@@ -49,6 +49,7 @@ struct CcsData                  *ShmCcsData;
 
 byte gun_count;
 int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+struct timeval _chk_ratingPower_timeout[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 float _pow_1 = 0;
 float _cur_1 = 0;
@@ -1786,6 +1787,20 @@ void ClearAbnormalStatus_CCS(byte gun_index)
         memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
         isCleanCheck = true;
     }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023818", 6) == EQUAL &&
+            ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound == YES)
+    {
+        memcpy(code, "023818", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023819", 6) == EQUAL &&
+            ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq == YES)
+    {
+        memcpy(code, "023819", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
     else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023823", 6) == EQUAL &&
              ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join == YES)
     {
@@ -2213,6 +2228,13 @@ void ClearAbnormalStatus_CCS(byte gun_index)
         memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
         isCleanCheck = true;
     }
+    else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023893", 6) == EQUAL &&
+             ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey == YES)
+    {
+        memcpy(code, "023893", 6);
+        memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
+        isCleanCheck = true;
+    }
 
     if (isCleanCheck)
     {
@@ -2300,6 +2322,8 @@ void ClearAbnormalStatus_CCS(byte gun_index)
                     if (strncmp(code, "023815", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_EVSE_match_session = NO;
                     if (strncmp(code, "023816", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_assoc_session = NO;
                     if (strncmp(code, "023817", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_vald_toggle = NO;
+                    if (strncmp(code, "023818", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound = NO;
+                    if (strncmp(code, "023819", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq = NO;
                     if (strncmp(code, "023823", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join = NO;
                     if (strncmp(code, "023824", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTCP_TT_match_join = NO;
                     if (strncmp(code, "023825", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_amp_map_exchange = NO;
@@ -2361,6 +2385,7 @@ void ClearAbnormalStatus_CCS(byte gun_index)
                     if (strncmp(code, "023890", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUnexpectVolBeforeCharing_Error = NO;
                     if (strncmp(code, "023891", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccNotReadyForCharging = NO;
                     if (strncmp(code, "023892", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = NO;
+                    if (strncmp(code, "023893", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey = NO;
                 }
             }
         }
@@ -2378,7 +2403,7 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
         return;
 
     memcpy(_chargingData[gun_index]->EvConnAlarmCode, string, 6);
-    printf("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s \n", _chargingData[gun_index]->EvConnAlarmCode);
+    PRINTF_FUNC("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s \n", _chargingData[gun_index]->EvConnAlarmCode);
 
     if (strcmp(string, "023700") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoEvCommFail = YES;
     if (strcmp(string, "023704") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoBatteryMalfun = YES;
@@ -2492,6 +2517,8 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
     if (strcmp(string, "023815") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_EVSE_match_session = YES;
     if (strcmp(string, "023816") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_assoc_session = YES;
     if (strcmp(string, "023817") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTT_EVSE_vald_toggle = YES;
+    if (strcmp(string, "023818") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmMnbcSound = YES;
+    if (strcmp(string, "023819") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccSlacTimeoutCmValidateReq = YES;
     if (strcmp(string, "023823") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUDP_TT_match_join = YES;
     if (strcmp(string, "023824") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTCP_TT_match_join = YES;
     if (strcmp(string, "023825") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsTP_amp_map_exchange = YES;
@@ -2553,6 +2580,7 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
     if (strcmp(string, "023890") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsUnexpectVolBeforeCharing_Error = YES;
     if (strcmp(string, "023891") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccNotReadyForCharging = YES;
     if (strcmp(string, "023892") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = YES;
+    if (strcmp(string, "023893") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey = YES;
 
     if (strcmp(string, "023702") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.GbEvCommFail = YES;
     if (strcmp(string, "023900") == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = YES;
@@ -2649,6 +2677,8 @@ void CANReceiver()
                     break;
                 }
             }
+
+            sleep(1);
         }
 
         for (byte _index = 0; _index < gun_count; _index++)
@@ -2738,7 +2768,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if (ShmCcsData->CommProtocol == 0x01)
+                            if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 for (byte _vCount = 0, _vPoint = 0; _vCount < frame.can_dlc; _vCount++)
                                 {
@@ -2777,8 +2807,8 @@ void CANReceiver()
                     case ACK_GET_OUTPUT_REQ:
                     {
                         _chargingData[targetGun]->EvBatterySoc = frame.data[1];
-                        _chargingData[targetGun]->EvBatterytargetVoltage = (((short) frame.data[3] << 8) + (short) frame.data[2]) / 10;
-                        _chargingData[targetGun]->EvBatterytargetCurrent = (((short) frame.data[5] << 8) + (short) frame.data[4]) / 10;
+                        _chargingData[targetGun]->EvBatterytargetVoltage = (float)((frame.data[3] << 8) + frame.data[2]) / 10;
+                        _chargingData[targetGun]->EvBatterytargetCurrent = (float)((frame.data[5] << 8) + frame.data[4]) / 10;
                         _chargingData[targetGun]->RemainChargingDuration = ((short) frame.data[7] << 8) + (short) frame.data[6];
 
                         if (_chargingData[targetGun]->Type == _Type_Chademo)
@@ -2799,7 +2829,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if(ShmCcsData->CommProtocol == 0x01)
+                            if(ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index].PresentMsgFlowStatus = frame.data[0];
                             }
@@ -2857,7 +2887,7 @@ void CANReceiver()
                         }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
-                            if (ShmCcsData->CommProtocol == 0x01)
+                            if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121)
                             {
                                 //ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index]. .ConnectorTemperatureP = frame.data[1];
                                 //ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index]. .ConnectorTemperatureN = frame.data[2];
@@ -2995,6 +3025,7 @@ void Initialization()
                 break;
             }
         }
+        sleep(1);
     }
 }
 
@@ -3152,7 +3183,7 @@ byte GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
         }
         else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip == YES)
         {
-            // 012236
+            // 012235
             *(reason + 5) = 0;
             *(reason + 4) = 1;
             *(reason + 3) = 2;
@@ -3209,7 +3240,7 @@ int main(int argc, char *argv[])
                 }
                 else if (_chargingData[_index]->Type == _Type_CCS_2)
                 {
-                    if (ShmCcsData->CommProtocol == 0x01 &&
+                    if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121 &&
                         ShmCcsData->V2GMessage_DIN70121[_chargingData[_index]->type_index].SelfTest_Comp != PASS)
                     {
                         SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
@@ -3268,6 +3299,8 @@ int main(int argc, char *argv[])
                         SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
                     else if (gun_count == 2)
                         SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+
+                    _chargingData[_index]->PowerConsumption = 0;
                 }
                     break;
                 case S_PREPARING_FOR_EV:
@@ -3309,6 +3342,7 @@ int main(int argc, char *argv[])
                         // 取得車端電池資訊 : 1.AC or DC ? 2.Total battery cap, 3.Max battery vol, 4.Max battery cur
                         GetEvBatteryInfo(_index, _chargingData[_index]->Evboard_id);
                     }
+                    gettimeofday(&_chk_ratingPower_timeout[_index], NULL);
                 }
                     break;
                 case S_PREPARING_FOR_EVSE:
@@ -3342,9 +3376,9 @@ int main(int argc, char *argv[])
 
                         //PRINTF_FUNC("To EV_%d GFD = %d \n",   _index, _chargingData[_index]->GroundFaultStatus);
 
-                        unsigned char _result = GFD_WAIT;
-                        _result = _chargingData[_index]->GroundFaultStatus;
+                        unsigned char _result = _chargingData[_index]->GroundFaultStatus;
 
+                        // GB & Chademo ~ Warning 也先算 Pass,因為 CCS 認證會驗 Warning 故不可更動
                         if(_chargingData[_index]->Type == _Type_Chademo ||
                            _chargingData[_index]->Type == _Type_GB)
                         {
@@ -3360,6 +3394,19 @@ int main(int argc, char *argv[])
                             PRINTF_FUNC("Unexpected GFD status : %d \n", _result);
                             _result = GFD_WAIT;
                         }
+                        else if (_result == GFD_WARNING ||
+                                 _result == GFD_PASS)
+                        {
+                            if (((GetTimeoutValue(_chk_ratingPower_timeout[_index]) / 1000) > 12000 &&
+                                 _chargingData[_index]->RealRatingPower > 0) ||
+                                (GetTimeoutValue(_chk_ratingPower_timeout[_index]) / 1000) > 14000)
+                            {
+                                PRINTF_FUNC("**********EvComm : _index= %d, RealRatingPower = %d \n",
+                                            _index, _chargingData[_index]->RealRatingPower);
+                            }
+                            else
+                                _result = GFD_WAIT;
+                        }
 
                         SetIsolationStatus(_index, _result, _chargingData[_index]->Evboard_id);
 
@@ -3376,7 +3423,8 @@ int main(int argc, char *argv[])
                     // 計算 Power
                     _chargingData[_index]->PresentChargingPower = ((float)((_chargingData[_index]->PresentChargingVoltage) * (_chargingData[_index]->PresentChargingCurrent)) / 1000);
 
-                    if (chargingTime[_index] == 0)
+                    if (chargingTime[_index] == 0 ||
+                        chargingTime[_index] > _chargingData[_index]->PresentChargedDuration)
                     {
                         chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
                     }
@@ -3393,6 +3441,7 @@ int main(int argc, char *argv[])
                             }
 
                             _chargingData[_index]->PresentChargedEnergy += changingPow;
+                            _chargingData[_index]->PowerConsumption += changingPow;
                             chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
                         }
                     }
@@ -3416,26 +3465,18 @@ int main(int argc, char *argv[])
                             SetPresentChargingOutputCap(_chargingData[0], _chargingData[1]);
                     }
 
-                    if (priorityLow == 1)
+                    if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
                     {
-                        // Chademo & GB/T GFD 失敗再通知
-                        if(_chargingData[_index]->Type == _Type_Chademo || _chargingData[_index]->Type == _Type_GB)
-                        {
-                            if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
-                            {
-                                SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
-                            }
-                        }
-                        // CCS will be continuous notify GFD state
-                        else if(_chargingData[_index]->Type == _Type_CCS_2)
-                        {
-                            SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
-                        }
-                        else
-                        {
-                            //NULL
-                        }
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
+                    else if(_chargingData[_index]->Type == _Type_CCS_2)
+                    {
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
 
+                    // GFD 失敗再通知
+                    if (priorityLow == 1)
+                    {
                         if(_chargingData[_index]->Type == _Type_CCS_2 &&
                            _chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
                         {
@@ -3466,11 +3507,23 @@ int main(int argc, char *argv[])
 
                         EvseStopChargingEvent(normalStop, stopReason, _chargingData[_index]->Evboard_id);
                     }
+
+                    if(_chargingData[_index]->Type == _Type_CCS_2)
+                    {
+                        SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+                    }
+
                     GetOutputReq(_index, _chargingData[_index]->Evboard_id);
                 }
                     break;
                 case S_COMPLETE:
                 {
+                    // 設定當前輸出
+                    if (gun_count == 1)
+                        SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
+                    else if (gun_count == 2)
+                        SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+
                     if (priorityLow == 1)
                     {
                         float maxVol, maxCur;

+ 0 - 1
EVSE/Projects/DW30/Apps/Module_EventLogging.c

@@ -180,7 +180,6 @@ void RemoveFaultCodeToBuf(unsigned char *Code)
     char _code[7];
     sprintf(_code,"%s", Code);
 
-    printf("********************* %s \n", _code);
     // 把相關的錯誤碼一次移除,避免重複顯示
     while(find)
     {

+ 243 - 101
EVSE/Projects/DW30/Apps/Module_InternalComm.c

@@ -46,16 +46,20 @@
 
 #define AC_DEFAULT_VOL      220
 
+#define NO_DEFINE           255
+#define NDEFAULT_AC_INDEX   2
+
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct FanModuleData            *ShmFanModuleData;
 struct RelayModuleData          *ShmRelayModuleData;
 struct LedModuleData            *ShmLedModuleData;
 struct PsuData                  *ShmPsuData;
+struct OCPP16Data               *ShmOCPP16Data;
 
 #define VIN_MAX_VOLTAGE_IEC     285 // 大於該值 : OVP
 #define VIN_MIN_VOLTAGE_IEC     160 // 小於該值 : UVP
-#define VIN_MAX_VOLTAGE_UL      315 // 大於該值 : OVP
+#define VIN_MAX_VOLTAGE_UL      315 // 大於該值 : OVP // 美規 (W)
 #define VIN_MIN_VOLTAGE_UL      210 // 小於該值 : UVP
 
 #define VIN_DROP_VOLTAGE    150 // 小於該值 : ac drop
@@ -64,7 +68,7 @@ struct PsuData                  *ShmPsuData;
 #define VOUT_MIN_VOLTAGE    150
 #define IOUT_MAX_CURRENT    50
 
-#define MAX_FAN_SPEED       13500
+#define MAX_FAN_SPEED       14000
 #define MIN_FAN_SPEED       3000
 #define NORMAL_FAN_SPEED    7000
 
@@ -74,6 +78,16 @@ struct PsuData                  *ShmPsuData;
 #define GFD_PRECHARGE       2
 #define GFD_CHARGING        3
 
+// LED Intensity (rate)
+#define LED_INTENSITY_DARKEST       0.2
+#define LED_INTENSITY_MEDIUM        0.6
+#define LED_INTENSITY_BRIGHTEST     1
+
+// EE Spec
+#define LED_BRIGHTNESS_LV_HIGH      1
+#define LED_BRIGHTNESS_LV_MID       0.5
+#define LED_BRIGHTNESS_LV_LOW       0.2
+
 // 最小切換 Relay 電壓
 #define SELF_TO_CHANGE_RELAY_STATUS         600
 // 透過電壓確認 Relay 是否搭上的依據電壓
@@ -415,7 +429,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
             }
             else
@@ -423,7 +437,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
             }
             else
@@ -431,7 +445,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Uvp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
             }
             else
@@ -441,7 +455,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
             }
             else
@@ -449,7 +463,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
             }
             else
@@ -457,7 +471,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Uvp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
             }
             else
@@ -469,7 +483,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
             }
             else
@@ -477,7 +491,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
             }
             else
@@ -485,7 +499,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_IEC)
             {
-                PRINTF_FUNC("In Ovp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
             }
             else
@@ -495,7 +509,7 @@ void GetPresentInputVol()
         {
             if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L1N_L12 = %d \n", inputVoltage.L1N_L12);
+                PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
             }
             else
@@ -503,7 +517,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L2N_L23 = %d \n", inputVoltage.L2N_L23);
+                PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
             }
             else
@@ -511,7 +525,7 @@ void GetPresentInputVol()
 
             if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_UL)
             {
-                PRINTF_FUNC("In Ovp L3N_L31 = %d \n", inputVoltage.L3N_L31);
+                PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
                 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
             }
             else
@@ -822,17 +836,14 @@ void GetAuxPower()
 
 void SetFanModuleSpeed()
 {
-    // 調整風扇速度要漸進式 : 500 rpm/p
     FanSpeed _fanSpeed;
 
     _setFanSpeed += fanSpeedSmoothValue;
 
     if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
         _setFanSpeed = ShmFanModuleData->SetFan1Speed;
-    {
-        _fanSpeed.speed[0] = _setFanSpeed;
-    }
 
+    _fanSpeed.speed[0] = _setFanSpeed;
     _fanSpeed.speed[1] = _setFanSpeed;
     _fanSpeed.speed[2] = _setFanSpeed;
     _fanSpeed.speed[3] = _setFanSpeed;
@@ -847,6 +858,15 @@ void SetFanModuleSpeed()
 //==========================================
 void SetK1K2RelayStatus(byte index)
 {
+    if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+    {
+        if(regRelay.relay_event.bits.Gun1_N == NO)
+            outputRelay.relay_event.bits.Gun1_N = YES;
+        else if (regRelay.relay_event.bits.Gun1_P == NO)
+            outputRelay.relay_event.bits.Gun1_P = YES;
+        return;
+    }
+
     if (_chargingData[index]->SystemStatus < S_PREPARING_FOR_EVSE)
     {
         if (_chargingData[index]->Evboard_id == 0x01)
@@ -1135,15 +1155,22 @@ bool IsNoneMatchLedColor()
 
 void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
 {
-    if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
+    byte _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST;
+
+    if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_DARKEST)
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST;
+    else if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_MEDIUM)
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM;
+
+    if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf)
     {
         if ((chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION) &&
             (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION))
         {
-            led_color.Connect_1_Green   = COLOR_MAX_LV;
+            led_color.Connect_1_Green   = _colorBuf;
             led_color.Connect_1_Blue    = COLOR_MIN_LV;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
-            led_color.Connect_2_Green   = COLOR_MAX_LV;
+            led_color.Connect_2_Green   = _colorBuf;
             led_color.Connect_2_Blue    = COLOR_MIN_LV;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
@@ -1153,10 +1180,10 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_1_Green   = COLOR_MIN_LV;
-            led_color.Connect_1_Blue    = COLOR_MAX_LV;
+            led_color.Connect_1_Blue    = _colorBuf;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
             led_color.Connect_2_Green   = COLOR_MIN_LV;
-            led_color.Connect_2_Blue    = COLOR_MAX_LV;
+            led_color.Connect_2_Blue    = _colorBuf;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
     }
@@ -1164,7 +1191,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
     {
         if (chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION)
         {
-            led_color.Connect_1_Green   = COLOR_MAX_LV;
+            led_color.Connect_1_Green   = _colorBuf;
             led_color.Connect_1_Blue    = COLOR_MIN_LV;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
         }
@@ -1172,14 +1199,14 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_1_Green   = COLOR_MIN_LV;
-            led_color.Connect_1_Blue    = COLOR_MAX_LV;
+            led_color.Connect_1_Blue    = _colorBuf;
             led_color.Connect_1_Red     = COLOR_MIN_LV;
         }
 
         // --------------------------------------------------------------------------
         if (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION)
         {
-            led_color.Connect_2_Green   = COLOR_MAX_LV;
+            led_color.Connect_2_Green   = _colorBuf;
             led_color.Connect_2_Blue    = COLOR_MIN_LV;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
@@ -1187,7 +1214,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
                  (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             led_color.Connect_2_Green   = COLOR_MIN_LV;
-            led_color.Connect_2_Blue    = COLOR_MAX_LV;
+            led_color.Connect_2_Blue    = _colorBuf;
             led_color.Connect_2_Red     = COLOR_MIN_LV;
         }
     }
@@ -1196,10 +1223,10 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
     {
         led_color.Connect_1_Green   = COLOR_MIN_LV;
         led_color.Connect_1_Blue    = COLOR_MIN_LV;
-        led_color.Connect_1_Red     = COLOR_MAX_LV;
+        led_color.Connect_1_Red     = _colorBuf;
         led_color.Connect_2_Green   = COLOR_MIN_LV;
         led_color.Connect_2_Blue    = COLOR_MIN_LV;
-        led_color.Connect_2_Red     = COLOR_MAX_LV;
+        led_color.Connect_2_Red     = _colorBuf;
     }
 
     if (_checkLedChanged > 0)
@@ -1227,7 +1254,6 @@ int InitShareMemory()
     int result = PASS;
     int MeterSMId;
 
-    //creat ShmSysConfigAndInfo
     if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1242,7 +1268,7 @@ int InitShareMemory()
         #endif
         result = FAIL;
      }
-     //creat ShmStatusCodeData
+
     if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1258,7 +1284,6 @@ int InitShareMemory()
         result = FAIL;
     }
 
-    //creat ShmFanModuleData
     if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1275,7 +1300,6 @@ int InitShareMemory()
      }
      memset(ShmFanModuleData,0,sizeof(struct FanModuleData));
 
-     //creat ShmRelayModuleData
     if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1292,7 +1316,6 @@ int InitShareMemory()
     }
     memset(ShmRelayModuleData,0,sizeof(struct RelayModuleData));
 
-    //creat ShmLedModuleData
     if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1309,7 +1332,6 @@ int InitShareMemory()
     }
     memset(ShmLedModuleData,0,sizeof(struct LedModuleData));
 
-    //creat ShmPsuData
     if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
     {
         #ifdef SystemLogMessage
@@ -1325,6 +1347,21 @@ int InitShareMemory()
         result = FAIL;
     }
 
+    if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ShmOCPP16Data NG \n");
+        #endif
+        result = FAIL;
+    }
+    else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ShmOCPP16Data NG \n");
+        #endif
+        result = FAIL;
+    }
+
     return result;
 }
 
@@ -1427,6 +1464,8 @@ void Initialization()
                 break;
             }
         }
+
+        sleep(1);
     }
 
     isPass = false;
@@ -1445,6 +1484,8 @@ void Initialization()
                     break;
                 }
             }
+
+            sleep(1);
         }
     }
 }
@@ -1546,7 +1587,7 @@ void CableCheckDetected(byte index)
     if ((_chargingData[index]->Type >= _Type_Chademo && _chargingData[index]->Type <= _Type_GB) ||
         (_chargingData[index]->Type == 0x09 && ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag))
     {
-        if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_CHARGING) ||
+        if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_TERMINATING) ||
             (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
             if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE &&
@@ -1559,16 +1600,13 @@ void CableCheckDetected(byte index)
             {
                 SetGfdConfig(index, GFD_PRECHARGE);
             }
-            else if (_chargingData[index]->SystemStatus <= S_CHARGING)
+            else if (_chargingData[index]->SystemStatus >= S_CHARGING &&
+                     _chargingData[index]->SystemStatus <= S_TERMINATING)
             {
-                if (_chargingData[index]->Type == _Type_CCS_2)
-                {
-                    SetGfdConfig(index, GFD_CHARGING);
-                }
-                else
-                {
+                if (_chargingData[index]->Type == _Type_GB || _chargingData[index]->Type == _Type_Chademo)
                     SetGfdConfig(index, GFD_IDLE);
-                }
+                else
+                    SetGfdConfig(index, GFD_CHARGING);
             }
         }
         else if(_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING
@@ -1668,6 +1706,7 @@ void CheckRelayWeldingStatus(byte index)
 void GetPsuTempForFanSpeed()
 {
     char temp = 0;
+
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
     {
         for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
@@ -1677,6 +1716,8 @@ void GetPsuTempForFanSpeed()
         }
     }
 
+    ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = temp;
+
     if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO)
     {
         if (ShmFanModuleData->TestFanSpeed == NORMAL_FAN_SPEED)
@@ -1694,6 +1735,65 @@ void GetPsuTempForFanSpeed()
     }
 }
 
+void GetFanSpeedByFunction()
+{
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
+        return;
+
+    // 風控修改 :
+    // ******************************************************* //
+    //
+    //       當前PSU輸出總 KW       PSU Temp
+    // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
+    //       當前樁最大功率 KW         45
+    //
+    // ******************************************************* //
+
+    // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower
+    unsigned int _maxPower = ShmPsuData->SystemAvailablePower;
+    // 當前PSU輸出總 KW & PSU Temp :
+    unsigned char temp = 0;
+    float power = 0;
+
+    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+    {
+        for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
+        {
+            if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp)
+                temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp;
+        }
+        power += (_chargingData[index]->PresentChargingPower * 10);
+    }
+
+    double _pw_rate = 0;
+    if (_maxPower > 0)
+        _pw_rate = power / (double)_maxPower;
+    double _temp_rate = 0;
+    if (temp > 0)
+        _temp_rate = (double)temp / 45;
+    unsigned char _temp_diff = 0;
+    if (temp > 45)
+        _temp_diff = temp - 45;
+
+    ShmFanModuleData->TestFanSpeed = ((30 * _pw_rate * _temp_rate + 14 * _temp_diff) / 100) * MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED)
+        ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed < 0)
+            ShmFanModuleData->TestFanSpeed = 0;
+//
+//  printf("power = %f \n", power);
+//  printf("_maxPower = %d \n", _maxPower);
+//  printf("temp = %d \n", temp);
+//
+//  printf("_pw_rate = %f \n", _pw_rate);
+//  printf("_temp_rate = %f \n", _temp_rate);
+//  printf("_temp_diff = %d \n", _temp_diff);
+//  printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff));
+//  printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed);
+}
+
 void GetAcStatus()
 {
     if (Query_AC_Status(Uart5Fd, Addr.AcPlug, &acStatus) == PASS)
@@ -1789,10 +1889,61 @@ void ChangeStartOrStopDateTime(byte isStart)
         strcpy((char *)ac_chargingInfo[0]->StopDateTime, cmdBuf);
 }
 
+void OcppStartTransation(byte gunIndex)
+{
+    if(strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL)
+        strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag);
+    else
+        strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId);
+
+    PRINTF_FUNC("AC IdTag = %s \n", ShmOCPP16Data->StartTransaction[gunIndex].IdTag);
+    ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionReq = YES;
+}
+
+void OcppStopTransation(byte gunIndex)
+{
+    if(strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL)
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag);
+    else
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId);
+
+    PRINTF_FUNC("AC IdTag = %s \n", ShmOCPP16Data->StopTransaction[gunIndex].IdTag);
+    ShmOCPP16Data->CpMsg.bits[gunIndex].StopTransactionReq = YES;
+}
+
+bool OcppRemoteStop(byte gunIndex)
+{
+    bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq;
+
+    if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES)
+    {
+        strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Remote");
+        ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO;
+    }
+
+    return result;
+}
+
+unsigned char isModeChange()
+{
+    unsigned char result = NO;
+
+    if(ac_chargingInfo[0]->SystemStatus != ac_chargingInfo[0]->PreviousSystemStatus)
+    {
+        result = YES;
+        ac_chargingInfo[0]->PreviousSystemStatus = ac_chargingInfo[0]->SystemStatus;
+    }
+
+    return result;
+}
+
 void AcChargeTypeProcess()
 {
     if (acgunCount > 0)
     {
+        //ac_chargingInfo[0]->SelfTest_Comp = YES;
+        //ac_chargingInfo[0]->IsModeChagned = PASS;
+        //---------------------------------------------
         if (ac_chargingInfo[0]->SelfTest_Comp == NO)
         {
             ac_chargingInfo[0]->IsModeChagned = NO;
@@ -1810,15 +1961,18 @@ void AcChargeTypeProcess()
             GetAcAlarmCode();
 
             byte _status = S_NONE;
-            bool _isStatusChanged = false;
 
-            if (acStatus.CpStatus == AC_SYS_A || ac_chargingInfo[0]->IsErrorOccur)
+            if (ac_chargingInfo[0]->SystemStatus == S_IDLE && ac_chargingInfo[0]->IsErrorOccur)
+            {
+                _status = S_ALARM;
+            }
+            else if (acStatus.CpStatus == AC_SYS_A || ac_chargingInfo[0]->IsErrorOccur)
             {
                 if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
                     _status = S_TERMINATING;
                 else if (ac_chargingInfo[0]->SystemStatus >= S_TERMINATING)
                 {
-                    if (GetTimeoutValue(_ac_charging_comp) >= 10000000)
+                    if (GetTimeoutValue(_ac_charging_comp) >= 10000000 && acStatus.CpStatus == AC_SYS_A)
                         _status = S_IDLE;
                 }
                 else
@@ -1832,21 +1986,21 @@ void AcChargeTypeProcess()
                 else if (GetTimeoutValue(_ac_preparing) >= 30000000)
                     _status = S_IDLE;
             }
-            else if (acStatus.CpStatus == AC_SYS_B &&
+            else if ((acStatus.CpStatus == AC_SYS_B || ac_chargingInfo[0]->ConnectorPlugIn == AC_SYS_B) &&
                      ac_chargingInfo[0]->IsAvailable &&
                      !ac_chargingInfo[0]->IsErrorOccur &&
                      (ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
                       ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE))
             {
-                if (ShmSysConfigAndInfo->SysInfo.OrderCharging != FAIL &&
-                    ShmSysConfigAndInfo->SysInfo.OrderCharging == DEFAULT_AC_INDEX)
+                if (ac_chargingInfo[0]->RemoteStartFlag == YES)
                 {
                     PRINTF_FUNC("** AC Remote \n");
+                    ac_chargingInfo[0]->RemoteStartFlag = NO;
                     strcpy((char *)ac_chargingInfo[0]->StartUserId, "");
                     ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO;
                     _status = S_PREPARNING;
                 }
-                else
+                else if (ShmSysConfigAndInfo->SysInfo.OrderCharging == NO_DEFINE)
                 {
                     PRINTF_FUNC("** UserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
                     strcpy((char *)ac_chargingInfo[0]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId);
@@ -1856,12 +2010,16 @@ void AcChargeTypeProcess()
                     _status = S_PREPARNING;
                 }
             }
+            else if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
+            {
+                if (OcppRemoteStop(1))
+                    _status = S_TERMINATING;
+            }
 
             //printf("_status = %d \n", _status);
 
             if (_status != S_NONE && ac_chargingInfo[0]->SystemStatus != _status)
             {
-                _isStatusChanged = true;
                 ac_chargingInfo[0]->SystemStatus = _status;
             }
 
@@ -1869,12 +2027,15 @@ void AcChargeTypeProcess()
             switch(ac_chargingInfo[0]->SystemStatus)
             {
                 case S_IDLE:
+                case S_ALARM:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ac_chargingInfo[0]->PresentChargedEnergy = 0.0;
                         ac_chargingInfo[0]->PresentChargingVoltage = 0;
                         ac_chargingInfo[0]->ChargingFee = 0.0;
+                        strcpy((char *)ac_chargingInfo[0]->StartDateTime, "");
+                        strcpy((char *)ac_chargingInfo[0]->StopDateTime, "");
                         _beforeChargingTotalEnergy = 0.0;
                     }
 
@@ -1883,16 +2044,18 @@ void AcChargeTypeProcess()
                     break;
                 case S_PREPARNING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
                         ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
-                        ShmSysConfigAndInfo->SysInfo.OrderCharging = FAIL;
+                        if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE)
+                            ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE;
                         gettimeofday(&_ac_preparing, NULL);
                     }
 
                     if (GetChargingEnergy() == PASS)
                     {
+                        //ac_chargingInfo[0]->PresentChargedEnergy = acChargingEnergy.Energy / 100;
                         _beforeChargingTotalEnergy = acChargingEnergy.Energy;
                     }
 
@@ -1902,9 +2065,10 @@ void AcChargeTypeProcess()
                     break;
                 case S_CHARGING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ftime(&_ac_startChargingTime);
+                        OcppStartTransation(1);
                         ChangeStartOrStopDateTime(YES);
                         ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
                     }
@@ -1924,12 +2088,12 @@ void AcChargeTypeProcess()
                     }
 
                     if (GetChargingCurrent() == PASS)
-                        ac_chargingInfo[0]->PresentChargingPower = (AC_DEFAULT_VOL * (acChargingCurrent.OuputCurrentL1 / 10)) / 1000;
+                        ac_chargingInfo[0]->PresentChargingPower = (((float)(AC_DEFAULT_VOL * acChargingCurrent.OuputCurrentL1) / 10) / 1000);
 
                     ftime(&_ac_endChargingTime);
                     ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
                     ac_chargingInfo[0]->PresentChargingVoltage = AC_DEFAULT_VOL;
-                    ac_chargingInfo[0]->PresentChargingCurrent = acChargingCurrent.OuputCurrentL1 / 10;
+                    ac_chargingInfo[0]->PresentChargingCurrent = ((float)acChargingCurrent.OuputCurrentL1 / 10);
 
                     // 用以判斷是否有在輸出
                     ac_chargingInfo[0]->IsCharging = acStatus.RelayStatus;
@@ -1940,7 +2104,7 @@ void AcChargeTypeProcess()
                     break;
                 case S_TERMINATING:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         ChangeStartOrStopDateTime(NO);
                         gettimeofday(&_ac_charging_comp, NULL);
@@ -1953,10 +2117,16 @@ void AcChargeTypeProcess()
                     break;
                 case S_COMPLETE:
                 {
-                    if (_isStatusChanged)
+                    if (isModeChange())
                     {
                         gettimeofday(&_ac_charging_comp, NULL);
                         ftime(&_ac_endChargingTime);
+                        if (strcmp((char *)ac_chargingInfo[0]->StartDateTime, "") != EQUAL)
+                        {
+                            // AC 固定為第2把槍
+                            OcppStopTransation(1);
+                        }
+
                         ChangeStartOrStopDateTime(NO);
                         ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
                     }
@@ -2124,7 +2294,9 @@ int main(void)
             // 橋接 relay
             SetParalleRelayStatus();
 
-            if (isCharging)
+            // 搭上 AC Contactor
+            if (isCharging ||
+                (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE))
             {
                 isStopChargingCount = false;
                 outputRelay.relay_event.bits.AC_Contactor = YES;
@@ -2143,6 +2315,9 @@ int main(void)
                 }
             }
 
+            if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+                outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
+
             // 搭上/鬆開 Relay
             if(IsNoneMatchRelayStatus())
             {
@@ -2171,54 +2346,21 @@ int main(void)
 
         if (ShmFanModuleData->SelfTest_Comp == YES)
         {
-            // 風控修改 :
-            // ******************************************************* //
-            //
-            //       當前PSU輸出總 KW       PSU Temp
-            // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
-            //       當前樁最大功率 KW         45
-            //
-            // ******************************************************* //
             if (GetTimeoutValue(_priority_time) / 1000 >= 1000)
             {
-                GetPsuTempForFanSpeed();
-
+                //GetPsuTempForFanSpeed();
+                GetFanSpeedByFunction();
                 GetFanSpeed();
                 ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
 
                 gettimeofday(&_priority_time, NULL);
-                if (isCharging)
-                {
-                    // 在還沒問到 PSU 溫度~ 還是要有個最小轉速
-                    ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
 
-                    if (ShmFanModuleData->TestFanSpeed > 0)
-                    {
-                        ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-                    }
-                }
-                else
-                {
-                    ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-                    ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
+                ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+                ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+
 
-                    // 停止時,如溫度還是很高,則需要維持該轉速直到溫度降低
-                    if (ShmFanModuleData->TestFanSpeed >= MAX_FAN_SPEED)
-                    {
-                        ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-                        ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-                    }
-                }
 
                 //PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
                 SetFanModuleSpeed();

+ 34 - 22
EVSE/Projects/DW30/Apps/Module_LcmControl.c

@@ -888,10 +888,7 @@ void ProcessPageInfo()
                 if (ShmSysConfigAndInfo->SysConfig.isQRCode)
                 {
                     needReloadQr = false;
-                    char QrCodeContent[128];
-                    strcpy(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
-                    strcat(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber);
-                    ChangeQrCode_Idle(QrCodeContent);
+                    ChangeQrCode_Idle((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
                 }
             }
         }
@@ -952,17 +949,20 @@ void ProcessPageInfo()
                     if (_currentPage == _LCM_CHARGING)
                     {
                         ChangeAcBattMapAndValue(_LCM_CHARGING);
-                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0)
+                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0 &&
+                            ac_chargingInfo[0]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(ac_chargingInfo[0]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                             ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
                         else
                             ChangeChargingEnergyValue(0);
@@ -975,17 +975,20 @@ void ProcessPageInfo()
                     else if (_currentPage == _LCM_COMPLETE)
                     {
                         ChangeAcBattMapAndValue(_LCM_COMPLETE);
-                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0)
+                        if (ac_chargingInfo[0]->PresentChargedDuration >= 0 &&
+                            ac_chargingInfo[0]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(ac_chargingInfo[0]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1 &&
+                            ac_chargingInfo[0]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1&&
+                            ac_chargingInfo[0]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                         {
                             ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
 
@@ -1066,17 +1069,20 @@ void ProcessPageInfo()
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                         ChangeBattMapAndValue(_LCM_CHARGING, _chargingInfoData[i]->EvBatterySoc);
-                        if (_chargingInfoData[i]->PresentChargedDuration >= 0)
+                        if (_chargingInfoData[i]->PresentChargedDuration >= 0 &&
+                            _chargingInfoData[i]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(_chargingInfoData[i]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (_chargingInfoData[i]->PresentChargingPower >= 0)
+                        if (_chargingInfoData[i]->PresentChargingPower >= 0 &&
+                            _chargingInfoData[i]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
+                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1 &&
+                            _chargingInfoData[i]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
                         else
                             ChangeChargingEnergyValue(0);
@@ -1092,17 +1098,20 @@ void ProcessPageInfo()
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                         ChangeBattMapAndValue(_LCM_COMPLETE, _chargingInfoData[i]->EvBatterySoc);
-                        if (_chargingInfoData[i]->PresentChargedDuration >= 0)
+                        if (_chargingInfoData[i]->PresentChargedDuration >= 0 &&
+                            _chargingInfoData[i]->PresentChargedDuration <= TIME_MAX_SEC)
                             ChangeChargingTime(_chargingInfoData[i]->PresentChargedDuration);
                         else
                             ChangeChargingTime(0);
 
-                        if (_chargingInfoData[i]->PresentChargingPower >= 0)
+                        if (_chargingInfoData[i]->PresentChargingPower >= 0 &&
+                            _chargingInfoData[i]->PresentChargingPower <= POWER_MAX_KW)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                             ChangeChargingPowerValue(0);
 
-                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
+                        if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1 &&
+                            _chargingInfoData[i]->PresentChargedEnergy <= ENERGY_MAX_KWH)
                         {
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
 
@@ -1153,10 +1162,7 @@ void ProcessPageInfo()
                         if (ShmSysConfigAndInfo->SysConfig.isQRCode)
                         {
                             needReloadQr = false;
-                            char QrCodeContent[128];
-                            strcpy(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
-                            strcat(QrCodeContent, (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber);
-                            ChangeQrCode_Charge(QrCodeContent);
+                            ChangeQrCode_Charge((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
                         }
                     }
                 }
@@ -1206,12 +1212,14 @@ void Initialization()
         {
             if (!FindChargingInfoData(_index, &_chargingInfoData[0]))
             {
-                DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
+                DEBUG_ERROR("LcmComm (main) : FindChargingInfoData false \n");
                 isPass = false;
                 count--;
                 break;
             }
         }
+
+        sleep(1);
     }
 
     isPass = false;
@@ -1225,11 +1233,13 @@ void Initialization()
             {
                 if (!FindAcChargingInfoData(_index, &ac_chargingInfo[0]))
                 {
-                    DEBUG_ERROR("EvComm : FindAcChargingInfoData false \n");
+                    DEBUG_ERROR("LcmComm : FindAcChargingInfoData false \n");
                     isPass = false;
                     break;
                 }
             }
+
+            sleep(1);
         }
     }
 
@@ -1261,6 +1271,8 @@ int main(void)
     Initialization();
 
     //return 0;
+    for(byte i = 0; i < 3; i++)
+        ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
 
     while(_port != -1)
     {

+ 4 - 0
EVSE/Projects/DW30/Apps/Module_LcmControl.h

@@ -44,6 +44,10 @@ struct FanModuleData            *ShmFanModuleData;
 #define NO_DEFINE           255
 #define DEFAULT_AC_INDEX    2
 
+#define TIME_MAX_SEC        2592000 // 一個月,秒數
+#define POWER_MAX_KW        5000
+#define ENERGY_MAX_KWH      5000
+
 #define CMD_TITLE_1             0x5A
 #define CMD_TITLE_2             0xA5
 #define CMD_READ                0x80

+ 2 - 1
EVSE/Projects/DW30/Apps/Module_PrimaryComm.c

@@ -439,7 +439,8 @@ int main(void)
         {
             if ((GetTimeoutValue(_flash_time) / 1000) > 5000)
             {
-                flash = YES;
+                if (flash == NO)
+                    flash = YES;
 
                 SetOutputGpio(flash);
                 gettimeofday(&_flash_time, NULL);

+ 251 - 136
EVSE/Projects/DW30/Apps/Module_PsuComm.c

@@ -348,14 +348,43 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     int _groupPower = 0, _groupCurrent = 0;
     byte group = FindTargetGroup(address);
+    float _chargingVol = 0, _targetVol = 0;
 
     if (group == 1)
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
 
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+    {
+        for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
+        {
+            if (chargingInfo[groupIndex]->EvBatteryMaxVoltage > 0)
+            {
+                _chargingVol = chargingInfo[groupIndex]->EvBatteryMaxVoltage;
+                _targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
+                break;
+            }
+        }
+    }
+
     if (chargingInfo[group]->DeratingChargingCurrent == 0)
-        ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+    {
+        // 在還沒取得真正可輸出的電流前,依照 GFD 階段得到的真正 POWER / 模塊個數 / 車子電池最大電壓
+        if (ShmPsuData->PsuGroup[group].GroupRealOutputPower > 0 && _chargingVol > 0)
+        {
+            ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent =
+                    ((ShmPsuData->PsuGroup[group].GroupRealOutputPower / ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity) * 1000 / (int)_chargingVol) * 10;
+        }
+        else
+        {
+            // 注一 : 獲取模塊最大輸出能力 (忽視 Derating 狀態),所以這邊需要限制實際可輸出的電流
+            if (ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent <= 0)
+                ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+        }
+    }
     else
+    {
         ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
+    }
 
     ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
     // 總和該 Group 的可輸出電流
@@ -371,7 +400,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     chargingInfo[group]->MaximumChargingVoltage = maxVol;
 
-    int _power = 0, _current = 0, _ratingcurrent = 0;
+    int _power = 0, _current = 0, _ratingcurrent = 0, _sysRealPower = 0;
     bool isGetAllDeratingCurrent = true;
 
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
@@ -379,6 +408,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
         _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
         _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
         _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent;
+        _sysRealPower += ShmPsuData->PsuGroup[index].GroupRealOutputPower;
         if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage >= PSU_MIN_VOL &&
             chargingInfo[index]->DeratingChargingCurrent == 0)
             isGetAllDeratingCurrent = false;
@@ -386,6 +416,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
     // 如果不是所有群都得到 Derating current,則先不採樣該次的 ratingCurrent
     if (!isGetAllDeratingCurrent) _ratingcurrent = 0;
+    if (_ratingcurrent != 0) _current = _ratingcurrent;
 
     ShmPsuData->SystemAvailableCurrent = _current;
     ShmPsuData->SystemAvailablePower = _power;
@@ -397,6 +428,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
         int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
         int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
         int ratingCur = chargingInfo[group]->DeratingChargingCurrent;
+        int gpRealPow = ShmPsuData->PsuGroup[group].GroupRealOutputPower;
 
         if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
             ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
@@ -412,25 +444,24 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
         GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur);
 
-//      if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
-//               ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
-//      {
-//          chargingInfo[group]->AvailableChargingCurrent = DERATING_RANGE;
-//          chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
-//      }
-//      else
+
+        // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
+        // 1. 如不是最大充
+        // 2. 智能切換成均充過程
+        chargingInfo[group]->AvailableChargingCurrent = halfCur;
+        chargingInfo[group]->AvailableChargingPower = halfPow;
+        chargingInfo[group]->RealRatingPower = gpRealPow;
+
+        if(chargingInfo[group]->DeratingChargingCurrent > 0)
         {
-            // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
-            // 1. 如不是最大充
-            // 2. 智能切換成均充過程
-            chargingInfo[group]->AvailableChargingCurrent = halfCur;
-            chargingInfo[group]->AvailableChargingPower = halfPow;
+            unsigned short _powBuf = 0;
+            _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW
 
-            if(chargingInfo[group]->DeratingChargingCurrent > 0)
+            if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower ||
+                chargingInfo[group]->EvBatterytargetVoltage > 0)
             {
-                chargingInfo[group]->RealRatingPower = (chargingInfo[group]->DeratingChargingCurrent * chargingInfo[group]->PresentChargingVoltage) / 100000;
+                ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf;
             }
-            //printf("(Aver.) RealRatingPower = %d \n", chargingInfo[group]->RealRatingPower);
         }
     }
     else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
@@ -444,6 +475,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
                 chargingInfo[count]->MaximumChargingVoltage = maxVol;
                 chargingInfo[count]->AvailableChargingCurrent = _current;
                 chargingInfo[count]->AvailableChargingPower = _power;
+                chargingInfo[count]->RealRatingPower = _sysRealPower;
             }
         }
         else
@@ -451,13 +483,21 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
             // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
             chargingInfo[group]->AvailableChargingCurrent = _current;
             chargingInfo[group]->AvailableChargingPower = _power;
+            chargingInfo[group]->RealRatingPower = _sysRealPower;
         }
 
-        if(_ratingcurrent > 0)
+        if(chargingInfo[group]->DeratingChargingCurrent > 0)
         {
-            chargingInfo[group]->RealRatingPower = (_ratingcurrent * chargingInfo[group]->PresentChargingVoltage) / 100000;
+            unsigned short _powBuf = 0;
+            _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW
+
+            if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower ||
+                    chargingInfo[group]->EvBatterytargetVoltage > 0 ||
+                    _targetVol > 0)
+            {
+                ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf;
+            }
         }
-        //printf("(Max.) RealRatingPower = %d \n", chargingInfo[group]->RealRatingPower);
     }
 }
 
@@ -635,10 +675,11 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
     bool isPass = true;
     int totalCur = 0;
+    byte sampleCount = 8;
 
     if (Iavail == 0)
     {
-        for (byte count = 0; count < 2; count++)
+        for (byte count = 0; count < sampleCount; count++)
         {
             chargingInfo[group]->SampleChargingCur[count] = Iavail;
         }
@@ -651,7 +692,7 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
             totalCur += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
         }
 
-        for (byte count = 0; count < 2; count++)
+        for (byte count = 0; count < sampleCount; count++)
         {
             if (chargingInfo[group]->SampleChargingCur[count] == 0)
             {
@@ -672,106 +713,126 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
     if (isPass)
     {
-        //PRINTF_FUNC("rating pass value = %d \n", totalCur);
         chargingInfo[group]->DeratingChargingCurrent = totalCur;
     }
 }
 
-//==========================================
-// 特規用指令
-//==========================================
-void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
-                              unsigned short outputCur_s, unsigned short outputPower,
-                              unsigned char Temperature)
+void GetPresentOutputFCallback(byte group, float outVol, float outCur)
 {
-    if (ShmPsuData->Work_Step < GET_SYS_CAP)
-        return;
-
-    unsigned short outVol = outputVol_s;
-    unsigned short outCur = outputCur_s;
-
-    if (IsOverModuleCount(address))
-        return;
+    // isinf : -1 = 負無窮,1 = 正無窮,0 = 其他
+    if (isinf(outVol) == 0)
+        ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = (unsigned short)(outVol * 10);
+    else
+        ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = 0;
 
-    byte group = FindTargetGroup(address);
+    if (isinf(outCur) == 0)
+        ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = (unsigned short)(outCur * 10);
+    else
+        ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = 0;
 
-    if (group == 1)
-        address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
+                (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
+                (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING &&
+                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_COMP))
+            )
+        {
+            unsigned short outputVol = 0;
+            unsigned short outputCur = 0;
+            unsigned char _maxTOaver = 0;
 
-    // PSU Group - 電壓
-    ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outVol;
-    // PSU Group - 電流
-    ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outCur;
+            for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+            {
+                bool needtoAdd = true;
 
-    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
-        (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
-         (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING &&
-          ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_COMP)))
-    {
-        unsigned short outputVol = 0;
-        unsigned short outputCur = 0;
+                if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
+                    outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
 
-        for (byte index = 0; index < ShmPsuData->GroupCount; index++)
-        {
-            bool needtoAdd = true;
+                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A &&
+                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                {
+                    if (chargingInfo[index]->DividChargingCurrent == 0)
+                        needtoAdd = false;
+                    else
+                        _maxTOaver = index;
+                }
 
-            if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
-                outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
+                if (needtoAdd)
+                    outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
+            }
 
             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A &&
-                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
             {
-                if (chargingInfo[index]->DividChargingCurrent == 0)
-                    needtoAdd = false;
+                if (chargingInfo[_maxTOaver]->DividChargingCurrent != 0)
+                {
+                    float _cur_buf = outputCur;
+                    _cur_buf /= 10;
+                    chargingInfo[_maxTOaver]->PresentChargingCurrent = _cur_buf;
+                }
             }
 
-            if (needtoAdd)
-                outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
-        }
+            // 黑白機
+            if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
+            {
+                for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+                {
+                    float _vol_buf = outputVol;
+                    float _cur_buf = outputCur;
 
-        // 黑白機
-        if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
-        {
-            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+                    // EVSE - 電壓
+                    _vol_buf /= 10;
+                    chargingInfo[count]->PresentChargingVoltage = _vol_buf;
+
+                    _cur_buf /= 10;
+                    chargingInfo[count]->PresentChargingCurrent = _cur_buf;
+                }
+            }
+
+            if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
+                (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
             {
                 float _vol_buf = outputVol;
                 float _cur_buf = outputCur;
 
                 // EVSE - 電壓
                 _vol_buf /= 10;
-                chargingInfo[count]->PresentChargingVoltage = _vol_buf;
-                // EVSE - 電流
+                chargingInfo[group]->PresentChargingVoltage = _vol_buf;
+
                 _cur_buf /= 10;
-                chargingInfo[count]->PresentChargingCurrent = _cur_buf;
+                chargingInfo[group]->PresentChargingCurrent = _cur_buf;
             }
         }
-
-        if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
-            (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
+        else
         {
-            float _vol_buf = outputVol;
-            float _cur_buf = outputCur;
+            float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+            float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
 
             // EVSE - 電壓
             _vol_buf /= 10;
             chargingInfo[group]->PresentChargingVoltage = _vol_buf;
-            // EVSE - 電流
+
             _cur_buf /= 10;
             chargingInfo[group]->PresentChargingCurrent = _cur_buf;
         }
-    }
-    else
-    {
-        float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
-        float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
-
-        // EVSE - 電壓
-        _vol_buf /= 10;
-        chargingInfo[group]->PresentChargingVoltage = _vol_buf;
-        // EVSE - 電流
-        _cur_buf /= 10;
-        chargingInfo[group]->PresentChargingCurrent = _cur_buf;
-    }
+}
+
+//==========================================
+// 特規用指令
+//==========================================
+void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
+                              unsigned short outputCur_s, unsigned short outputPower,
+                              unsigned char Temperature)
+{
+    if (ShmPsuData->Work_Step < GET_SYS_CAP)
+        return;
+
+    if (IsOverModuleCount(address))
+        return;
+
+    byte group = FindTargetGroup(address);
+
+    if (group == 1)
+        address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
 
     ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp1 = Temperature;
     ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp2 = Temperature;
@@ -929,6 +990,7 @@ void Initialization()
                 break;
             }
         }
+        sleep(1);
     }
 
     if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
@@ -951,6 +1013,8 @@ void Initialization()
             count = 1;
         else if (strcmp(EvsePower, "60") == EQUAL)
             count = 2;
+        else if (strcmp(EvsePower, "12") == EQUAL)
+            count = 4;
         else if (strcmp(EvsePower, "18") == EQUAL)
             count = 6;
         else if (strcmp(EvsePower, "36") == EQUAL)
@@ -1072,6 +1136,7 @@ int main(void)
     RefreshGetOutput(&GetPresentOutputCallback);
     RefreshFanInfo(&GetFanSpeedCallback);
     RefreshIavailable(&GetIavailableCallback);
+    RefreshGetOutputF(&GetPresentOutputFCallback);
 
     // GetPresentOutputCallback & GetStatusCallback
     AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
@@ -1098,6 +1163,7 @@ int main(void)
             if (!isInitialComp)
             {
                 ShmPsuData->Work_Step = INITIAL_START;
+                sleep(2);
                 InitialPsuData();
                 isInitialComp = YES;
             }
@@ -1135,8 +1201,6 @@ int main(void)
 
                 if (time > 2000)
                 {
-                    PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
-                                ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 //                  if (ShmPsuData->GroupCount == 0)
 //                      ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
                     // 分別取各群模組數量
@@ -1148,6 +1212,8 @@ int main(void)
                         // 取各群模組數量
                         GetModuleCount(index);
                     }
+                    PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
+                                ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 
                     // 發送取得目前全部模組數量
                     GetModuleCount(SYSTEM_CMD);
@@ -1172,7 +1238,6 @@ int main(void)
                         }
                     }
 
-                    _getCapDelayCount = 7;
                     gettimeofday(&_cmdSubPriority_time, NULL);
                 }
             }
@@ -1183,30 +1248,42 @@ int main(void)
 
                 if (time > 1000)
                 {
-                    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                    bool isFinish = true;
+                    for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++)
                     {
-                        // Pooling Status
-                        //GetStatus(index);
+                        if (strcmp((char *)ShmPsuData->PsuVersion[psuCount].FwPrimaryVersion, "") == EQUAL ||
+                                ShmPsuData->SystemAvailablePower <= 0 || ShmPsuData->SystemAvailableCurrent <= 0)
+                        {
+                            isFinish = false;
+                            break;
+                        }
+                    }
 
-                        // 取系統總輸出能力
-                        GetModuleCap(index);
+                    if (!isFinish)
+                    {
+                        for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                        {
+                            // Pooling Status
+                            //GetStatus(index);
+
+                            // 取系統總輸出能力
+                            GetModuleCap(index);
 
-                        // 取版號
-                        GetModuleVer(index);
+                            // 取版號
+                            GetModuleVer(index);
+                        }
                     }
-                    _getCapDelayCount--;
-                    gettimeofday(&_cmdSubPriority_time, NULL);
-                }
+                    else
+                    {
+                        // 判斷系統輸出額定功率與電流
+                        PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
+                                    ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
 
-                // 判斷系統輸出額定功率與電流
-                if (ShmPsuData->SystemAvailablePower > 0 && ShmPsuData->SystemAvailableCurrent > 0 &&
-                    _getCapDelayCount <= 0)
-                {
-                    PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
-                                ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
+                        PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
+                        ShmPsuData->Work_Step = BOOTING_COMPLETE;
+                    }
 
-                    PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
-                    ShmPsuData->Work_Step = BOOTING_COMPLETE;
+                    gettimeofday(&_cmdSubPriority_time, NULL);
                 }
             }
                 break;
@@ -1240,12 +1317,6 @@ int main(void)
 
                     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
                     {
-                        // Pooling Status
-                        //GetStatus(index);
-
-                        // 取得模塊輸出額定電流能力
-                        GetModuleIavailable(index);
-
                         if (chargingInfo[index]->SystemStatus == S_CHARGING)
                         {
                             isCharging = true;
@@ -1298,30 +1369,33 @@ int main(void)
                     // 取系統總輸出能力
                     GetModuleCap(groupIndex);
 
+                    // 取各群輸出電壓電流 (float)
+                    GetModuleOutputF(groupIndex);
+
+                    // 取得模塊輸出額定電流能力
+                    GetModuleIavailable(groupIndex);
+
                     // 針對各槍當前狀態,傳送需要回傳的資料指令
                     if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
                         (chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING && chargingInfo[groupIndex]->Type == _Type_GB) ||
                         (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
                     {
-                        if (time > 1500)
+                        if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
+                        evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
                         {
-                            if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
-                                evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
-                            {
-                                evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
-                                PRINTF_FUNC("groupIndex = %d, ev need vol = %f, evse output vol = %f \n", groupIndex,
-                                            (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
-                                            chargingInfo[groupIndex]->FireChargingVoltage);
-                            }
+                            evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
+                            PRINTF_FUNC("groupIndex = %d, ev need vol = %f, evse output vol = %f \n", groupIndex,
+                                        (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
+                                        chargingInfo[groupIndex]->FireChargingVoltage);
+                        }
 
-                            if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
-                                evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
-                            {
-                                evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
-                                PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
-                                            (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
-                                            (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
-                            }
+                        if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
+                            evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
+                        {
+                            evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
+                            PRINTF_FUNC("groupIndex = %d, ev need cur = %f, evse output cur = %f \n", groupIndex,
+                                        (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
+                                        (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
                         }
 
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
@@ -1348,6 +1422,7 @@ int main(void)
                             else
                             {
                                 chargingInfo[groupIndex]->DividChargingCurrent = 0;
+                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 0;
                             }
 
                             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
@@ -1456,8 +1531,10 @@ int main(void)
 
                                         if (reassignIndex != ELEMENT_NOT_FIND)
                                         {
-                                            if ((GetTimeoutValue(_derating_time) / 1000) <= 50)
+                                            if ((GetTimeoutValue(_derating_time) / 1000) <= 50 ||
+                                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag == 0)
                                             {
+                                                chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 1;
                                                 // A 模塊維持當前電壓電流
                                                 //PRINTF_FUNC("A : index = %d, cur = %d \n", groupIndex, ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
                                                 //PresentOutputVol(groupIndex, targetVol, ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
@@ -1502,10 +1579,8 @@ int main(void)
                                                      (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
                                                      (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10));
                                 }
-                                else
+                                else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                                 {
-                                    PRINTF_FUNC("set out (sys) value = %f, smart step = %d******** 4 \n",
-                                                chargingInfo[groupIndex]->EvBatterytargetCurrent, ShmSysConfigAndInfo->SysInfo.ReAssignedFlag);
                                     // 該充電槍的目標電壓與目標電流
                                     PresentOutputVol(SYSTEM_CMD,
                                                      (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
@@ -1852,6 +1927,46 @@ int main(void)
                 }
                     break;
             }
+            case _TEST_MODE:
+            {
+                // 在測試模式中,保持與模塊的通訊
+                int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
+
+                if (time > 1500)
+                {
+                    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+                    {
+                        // 取系統總輸出能力
+                        GetModuleCap(index);
+
+                        // 取各群輸出電壓電流 (float)
+                        GetModuleOutputF(index);
+                    }
+
+                    gettimeofday(&_cmdSubPriority_time, NULL);
+                }
+
+                byte _switch = 0x00;
+                if ((chargingInfo[0]->EvBatterytargetVoltage * 10) > 0 && (chargingInfo[0]->EvBatterytargetCurrent * 10) > 0)
+                    _switch = 0x01;
+
+                for (byte _groupCount_1 = 0; _groupCount_1 < conn_1_count; _groupCount_1++)
+                {
+                    SetDirModulePresentOutput(connector_1[_groupCount_1],
+                        (chargingInfo[0]->EvBatterytargetVoltage * 10),
+                        (chargingInfo[0]->EvBatterytargetCurrent * 10),
+                        _switch, _switch);
+                }
+
+                for (byte _groupCount_2 = 0; _groupCount_2 < conn_2_count; _groupCount_2++)
+                {
+                    SetDirModulePresentOutput(connector_2[_groupCount_2],
+                        (chargingInfo[0]->EvBatterytargetVoltage * 10),
+                        (chargingInfo[0]->EvBatterytargetCurrent * 10),
+                        _switch, _switch);
+                }
+            }
+                break;
         }
         usleep(20000);
     }

+ 0 - 1
EVSE/Projects/DW30/Apps/Module_PsuComm.h

@@ -41,7 +41,6 @@ struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANT
 bool isStartOutputSwitch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 struct timeval _cmdSubPriority_time;
-byte _getCapDelayCount;
 struct timeval _derating_time;
 struct timeval _max_time;
 

+ 373 - 0
EVSE/Projects/DW30/Apps/OutputTask.c

@@ -0,0 +1,373 @@
+/*
+ * OutputTask.c
+ *
+ *  Created on: 2020年2月25日
+ *      Author: 7564
+ */
+
+#include    "OutputTask.h"
+
+bool isOpen;
+
+int InitComPort()
+{
+    int fd;
+    struct termios tios;
+
+    fd = open(priPortName, O_RDWR);
+    if(fd<=0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("open 407 Communication port NG \n");
+        #endif
+        return -1;
+    }
+    ioctl (fd, TCGETS, &tios);
+    tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
+    tios.c_lflag = 0;
+    tios.c_iflag = 0;
+    tios.c_oflag = 0;
+    tios.c_cc[VMIN]=0;
+    tios.c_cc[VTIME]=(unsigned char)1;
+    tios.c_lflag=0;
+    tcflush(fd, TCIFLUSH);
+    ioctl (fd, TCSETS, &tios);
+
+    return fd;
+}
+
+unsigned long GetTimeoutValue(struct timeval _sour_time)
+{
+    struct timeval _end_time;
+    gettimeofday(&_end_time, NULL);
+
+    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+}
+
+void ShowMainMsg()
+{
+    printf("Max Vol : %f, Max Cur : %d, POW : %d \n", UnSafeDataInfo->PSU_VOLTAGE,
+            UnSafeDataInfo->PSU_CURRENT, UnSafeDataInfo->PSU_POWER);
+    printf("=> ");
+}
+
+void ChkButtonStatus()
+{
+    if (Button1 == PRESS && !leftBtnPush)
+    {
+        if(!leftBtnPush)
+        {
+            leftBtnPush = true;
+            if (_charging_mode == CHARGING_MODE_STOP)
+            {
+                _charging_mode = CHARGING_MODE_START;
+                printf("****************** Switch to Charging Mode ******************\n");
+            }
+        }
+        else if (Button1 == RELEASE)
+        {
+            if(leftBtnPush)
+            {
+                leftBtnPush = false;
+            }
+        }
+    }
+
+    if (Button2 == PRESS && !rightBtnPush)
+    {
+        if(!rightBtnPush)
+        {
+            rightBtnPush = true;
+            if (_charging_mode == CHARGING_MODE_START)
+            {
+                _charging_mode = CHARGING_MODE_TERMINATING;
+                printf("****************** Switch to Stop Mode ******************\n");
+            }
+        }
+        else if (Button2 == RELEASE)
+        {
+            if(rightBtnPush)
+            {
+                rightBtnPush = false;
+            }
+        }
+    }
+}
+
+void GetModuleCountCallback(byte group, byte count)
+{
+    printf("group = %d, count = %d \n", group, count);
+    if (group == SYSTEM_CMD)
+        UnSafeDataInfo->PSU_COUNT = count;
+}
+
+void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow)
+{
+    int _groupPower = 0, _groupCurrent = 0;
+
+    UnSafeDataInfo->PsuModule[address].PSU_VOLTAGE_INFO = maxVol;
+    UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO = maxCur;
+    UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO = totalPow;
+
+    for (byte index = 0; index < UnSafeDataInfo->PSU_COUNT; index++)
+    {
+        _groupCurrent += UnSafeDataInfo->PsuModule[address].PSU_CURRENT_INFO;
+        _groupPower += UnSafeDataInfo->PsuModule[address].PSU_POWER_INFO;
+    }
+
+    UnSafeDataInfo->PSU_VOLTAGE = maxVol;
+    UnSafeDataInfo->PSU_CURRENT = _groupCurrent;
+    UnSafeDataInfo->PSU_POWER = _groupPower;
+}
+
+void GetStatusCallback(byte group, byte address, byte temp, int alarm)
+{
+    printf("alarm = %d \n", alarm);
+}
+
+void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
+{
+    printf("vol1 = %d, vol2 = %d, vol3 = %d \n", vol1, vol2, vol3);
+}
+
+int CreateShareMemory()
+{
+    int MeterSMId;
+
+    if ((MeterSMId = shmget(ShmTestKey, sizeof(struct UnSafeData), IPC_CREAT | 0777)) < 0)
+    {
+        return 0;
+    }
+    else if ((UnSafeDataInfo = shmat(MeterSMId, NULL, 0))   == (void *) -1)
+    {
+        return 0;
+    }
+    memset(UnSafeDataInfo, 0, sizeof(struct UnSafeData));
+
+    return 1;
+}
+
+static void get_char(char *word)
+{
+    fd_set rfds;
+    struct timeval tv;
+
+    FD_ZERO(&rfds);
+    FD_SET(0, &rfds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 10; //wait input timout time
+
+    //if input
+    if (select(1, &rfds, NULL, NULL, &tv) > 0)
+    {
+        fgets(word, 128, stdin);
+    }
+}
+
+void GetInputString()
+{
+    char word[128];
+    char newString[7][10];
+    int i, j, ctr;
+
+    get_char(word);
+
+    if (strlen(word) == 0)
+        return;
+    //fgets(word, sizeof(word), stdin);
+
+    j = 0;
+    ctr = 0;
+    for (i = 0; i <= (strlen(word)); i++) {
+        if (word[i] == ' ' || word[i] == '\0' || word[i] == 10) {
+            newString[ctr][j] = '\0';
+            ctr++;
+            j = 0;
+        } else {
+            newString[ctr][j] = word[i];
+            j++;
+        }
+    }
+
+    VOLTAGE = atof(newString[0]);
+    CURRENT = atof(newString[1]);
+    if (VOLTAGE <= UnSafeDataInfo->PSU_VOLTAGE && CURRENT <= UnSafeDataInfo->PSU_CURRENT)
+    {
+        //printf("OutputVol = %f, OutputCur = %f \n", VOLTAGE, CURRENT);
+    }
+    else
+    {
+        ShowMainMsg();
+    }
+}
+
+void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
+{
+    //printf("address = %d, Iavail = %d, Vext = %d \n", address, Iavail, Vext);
+}
+
+void GetOutputAndTempCallback(byte address, unsigned short outputVol,
+        unsigned short outputCur, unsigned short outputPower, unsigned char Temperature)
+{
+    //printf("***Output Value and Temp*** address = %d, Vol = %d, Cur = %d, Pow = %d, Temp = %d \n",
+    //      address, outputVol, outputCur, outputPower, Temperature);
+}
+
+void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
+        unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
+{
+    //int alarm = (err2 << 24) | (err3 << 16) | (err4 << 8);
+
+    // err2 == state 2
+    // err3 == state 1
+    // err4 == state 0
+    //printf("***Status*** address = %d, alarm = %d \n", address, alarm);
+//  printf("***Status*** address = %d, err1 = %d, err2 = %d, err3 = %d, err4 = %d \n",
+//          address, err1,err2,err3,err4);
+}
+
+void GetModuleInputCallback(byte address, unsigned short inputR,
+        unsigned short inputS, unsigned short inputT)
+{
+
+}
+
+int main(void)
+{
+    isOpen =false;
+
+    if(CreateShareMemory() == 0)
+    {
+        printf("CreateShareMemory fail. \n");
+        return 0;
+    }
+    RefreshModuleCount(&GetModuleCountCallback);
+    RefreshAvailableCap(&GetAvailableCapCallback);
+
+    RefreshStatus(&GetStatusCallback);
+    RefreshInputVol(&GetInputVoltageCallback);
+
+    RefreshIavailable(&GetIavailableCallback);
+
+    AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
+    AutoMode_RefreshModuleStatus(&GetModuleStatusCallback);
+    AutoMode_RefreshModuleInput(&GetModuleInputCallback);
+
+    Uart1Fd = InitComPort();
+    libInitialize = InitialCommunication();
+
+    if (Uart1Fd < 0 || !libInitialize)
+    {
+        printf("Initial port fail. \n");
+        return 0;
+    }
+
+    sleep(5);
+    gettimeofday(&_cmdSubPriority_time, NULL);
+    VOLTAGE = 0.0;
+    CURRENT = 0.0;
+
+    SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+//  while (1)
+//  {
+//      printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
+//      SetWalkInConfig(0, YES, 0);
+//      SetWalkInConfig(1, NO, 0);
+//      printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+//      sleep(1);
+//  }
+//
+//  sleep(1);
+//      printf("++++++++++++++2++++++++++++++++++++++++++++++++++++++\n");
+//      SetWalkInConfig(SYSTEM_CMD, NO, 0);
+//      printf("++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+//  return 0;
+    while (1)
+    {
+        GetInputGpioStatus();
+        //ChkButtonStatus();
+        // 切換 Walk-in mode (default 5s -> 2s)
+        SetWalkInConfig(SYSTEM_CMD, NO, 0);
+
+        int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
+        while(isGetCount == YES)
+        {
+            if (_charging_mode == CHARGING_MODE_START)
+            {
+                // 取得模塊輸出額定電流能力
+                GetModuleIavailable(0);
+            }
+
+            GetInputString();
+            if (VOLTAGE > 150 && CURRENT >= 0)
+                _charging_mode = CHARGING_MODE_START;
+            else
+                _charging_mode = CHARGING_MODE_TERMINATING;
+            //printf("_charging_mode = %d \n", _charging_mode);
+            switch(_charging_mode)
+            {
+                case CHARGING_MODE_START:
+                {
+                    //if (!isOpen)
+                    {
+                        //SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
+                        //FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
+                        SetDirModulePresentOutput(0,
+                                                VOLTAGE * 10,
+                                                CURRENT * 10,
+                                                0x01,
+                                                0x01);
+                    }
+                    //PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10);
+                }
+                    break;
+                case CHARGING_MODE_TERMINATING:
+                {
+                    //if (isOpen)
+                    {
+                        SetDirModulePresentOutput(0,
+                            VOLTAGE * 10,
+                            CURRENT * 10,
+                            0x00,
+                            0x01);
+                        //SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+                        //FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+                    }
+                }
+                    break;
+            }
+            //GetStatus(0);
+            //GetModuleInput(0);
+            sleep(1);
+        }
+
+        if (UnSafeDataInfo->PSU_COUNT <= 0)
+        {
+            if (time > 1000)
+            {
+                printf("Step 1 : GetModuleCount...... \n");
+                GetModuleCount(SYSTEM_CMD);
+                gettimeofday(&_cmdSubPriority_time, NULL);
+            }
+        }
+        else if (time < 5000)
+        {
+            printf("Step 2 : GetModuleCap...... \n");
+            GetModuleCap(0);
+
+            SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+            FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+        }
+        else
+        {
+            ShowMainMsg();
+            isGetCount = YES;
+        }
+
+        sleep(1);
+    }
+
+    return 0;
+}
+
+

+ 174 - 0
EVSE/Projects/DW30/Apps/OutputTask.h

@@ -0,0 +1,174 @@
+/*
+ * OutputTask.h
+ *
+ *  Created on: 2020ฆ~2ค๋25ค้
+ *      Author: 7564
+ */
+
+#ifndef OUTPUTTASK_H_
+#define OUTPUTTASK_H_
+
+
+#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    <linux/can.h>
+#include    <linux/can/raw.h>
+#include    <arpa/inet.h>
+#include    <netinet/in.h>
+
+#include    <unistd.h>
+#include    <stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include    <errno.h>
+#include    <string.h>
+#include    <time.h>
+#include    <ctype.h>
+#include    <ifaddrs.h>
+#include    <stdbool.h>
+
+#define ShmTestKey  2001
+
+#define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
+#define PASS                1
+#define FAIL                -1
+#define YES                 1
+#define NO                  0
+#define PRESS               1
+#define RELEASE             0
+#define MAX_PSU_QUANTITY        62
+
+int Uart1Fd = -1;
+char *priPortName = "/dev/ttyS1";
+
+bool libInitialize = false;
+struct timeval _cmdSubPriority_time;
+
+unsigned char Button1 = RELEASE;
+unsigned char Button2 = RELEASE;
+bool leftBtnPush = false;
+bool rightBtnPush = false;
+
+unsigned char _psuCount = 0;
+unsigned char isGetCount = NO;
+
+float VOLTAGE;
+float CURRENT;
+
+struct PsuModuleInfo
+{
+    unsigned int    PSU_POWER_INFO;
+    float           PSU_VOLTAGE_INFO;
+    unsigned short  PSU_CURRENT_INFO;
+};
+
+struct UnSafeData
+{
+    unsigned char           PSU_COUNT;
+    struct PsuModuleInfo    PsuModule[MAX_PSU_QUANTITY];
+    unsigned int            PSU_POWER;
+    float                   PSU_VOLTAGE;
+    unsigned short          PSU_CURRENT;
+};
+
+struct UnSafeData           *UnSafeDataInfo;
+
+typedef struct GPIO_IN
+{
+    unsigned char AC_Connector;
+    unsigned char AC_MainBreaker;
+    unsigned char SPD;
+    unsigned char Door_Open;
+    unsigned char GFD[2];
+    unsigned char AC_Drop;
+    unsigned char Emergency_IO;
+
+    unsigned char Emergency_Btn;
+    unsigned char Button[2];
+    unsigned char Key[4];
+}Gpio_in;
+
+Gpio_in gpio_in;
+
+enum CHARGING_MODE
+{
+    CHARGING_MODE_STOP =            0x00,
+    CHARGING_MODE_START =           0x01,
+    CHARGING_MODE_TERMINATING =     0x10,
+};
+
+unsigned char _charging_mode = CHARGING_MODE_STOP;
+
+int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
+{
+    int len;
+    tcflush(fd,TCIOFLUSH);
+    if(write(fd, cmd, cmd_len) >= cmd_len)
+    {
+        usleep(50000);
+        len = read(fd, rx, 512);
+    }
+    else
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("Serial command %s response fail.\n", cmd);
+        #endif
+    }
+
+    return len;
+}
+
+unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, 0x0a, 0x00, 0x00, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 0)
+    {
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            Ret_Buf->Button[0]          = (rx[7] >> 1) & 0x01;
+            Ret_Buf->Button[1]          = (rx[7] >> 2) & 0x01;
+
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+void GetInputGpioStatus()
+{
+    if (Query_Gpio_Input(Uart1Fd, 0x04, &gpio_in) == PASS)
+    {
+        Button1 = gpio_in.Button[0];
+        Button2 = gpio_in.Button[1];
+    }
+}
+
+#endif /* OUTPUTTASK_H_ */

+ 188 - 20
EVSE/Projects/DW30/Apps/ReadCmdline.c

@@ -40,14 +40,26 @@
 typedef unsigned char           byte;
 #define PASS                1
 #define FAIL                -1
+#define EQUAL               0
 #define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
 #define NO_DEFINE           255
 #define DEFAULT_AC_INDEX    2
 
+#define AUTORUN_STEP1_TIME_START            140             // Minutes
+#define AUTORUN_STEP1_TIME_END              150
+#define AUTORUN_STEP2_TIME_START            210
+#define AUTORUN_STEP2_TIME_END              410
+#define AUTORUN_END_TIME                    480
+#define AUTORUN_CYCLE_COUNT                 30
+
 #define TTY_PATH            "/dev/tty"
 #define STTY_US             "stty raw -echo -F "
 #define STTY_DEF            "stty -raw echo -F "
 
+byte _curAutoRunCount = 0;
+byte _usingAutoRun = 0;
+struct timeval _autoTime;
+
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct PrimaryMcuData           *ShmPrimaryMcuData;
@@ -165,7 +177,8 @@ int InitShareMemory()
         else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
         {
             result = FAIL;
-        } else
+        }
+        else
         {
             //NULL
         }
@@ -237,11 +250,13 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
     struct timeval _end_time;
     gettimeofday(&_end_time, NULL);
 
-    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+    return (_end_time.tv_sec - _sour_time.tv_sec);
 }
 
 void RunStatusProc(char *v1, char *v2)
 {
+    printf("OrderCharging = %d \n", ShmSysConfigAndInfo->SysInfo.OrderCharging);
+    printf("WaitForPlugit = %d \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
     if (strcmp(v1, "ac") == 0)
     {
         if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
@@ -320,6 +335,26 @@ void RunCardProc(char *v1, char *v2)
 
 void RunGunPlugitProc(char *v1, char *v2)
 {
+    if (strcmp(v1, "ac") == 0)
+    {
+        if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
+        {
+            printf("FindChargingInfoData (AC) false \n");
+        }
+
+        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
+        {
+            // get
+            printf("ConnectorPlugIn = %d \n", ac_chargingInfo[0]->ConnectorPlugIn);
+        }
+        else
+        {
+            // set
+            ac_chargingInfo[0]->ConnectorPlugIn = atoi(v2);
+        }
+        return;
+    }
+
     int _index = atoi(v1);
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     {
@@ -411,7 +446,7 @@ void CreateOneError(char *v1)
 {
     int value = atoi(v1);
 
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = value;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = value;
     ShmSysConfigAndInfo->SysConfig.BillingData.isBilling = value;
 }
 
@@ -423,16 +458,17 @@ void GetAuthorizeFlag(char *v1)
         ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = atoi(v1);
 }
 
-void GetOrClearId(char *v1)
+void GetRelayStatus(char *v1)
 {
     int _index = atoi(v1);
-
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     {
         printf("FindChargingInfoData error\n");
         return;
     }
-    printf("Card Number = %s \n", _chargingData[_index]->StartUserId);
+
+    printf("RelayK1K2Status = %d \n", _chargingData[_index]->RelayK1K2Status);
+    printf("RelayKPK2Status = %d \n", _chargingData[_index]->RelayKPK2Status);
 }
 
 void FwUpdateFlagProc()
@@ -460,6 +496,19 @@ void SetCableChkStatus(char *v1, char *v2)
     _chargingData[_index]->GroundFaultStatus = atoi(v2);
 }
 
+void SetChargingInfoCCID(char *v1, char* v2)
+{
+    int _index = atoi(v1);
+    if (!FindChargingInfoData(_index, &_chargingData[0]))
+    {
+        printf ("FindChargingInfoData error\n");
+        return;
+    }
+
+    memcpy(_chargingData[_index]->EVCCID, v2, 8);
+    _chargingData[_index]->EVCCID[8] = '\0';
+}
+
 void SetPowerValue(char *v1, char *v2)
 {
     int _index = atoi(v1);
@@ -582,7 +631,7 @@ void GetAcInputVol()
            ShmSysConfigAndInfo->SysInfo.InputVoltageT);
 }
 
-void GetPsuInformation(char *v1)
+void GetPsuInformation(char *v1, char *v2, char *v3)
 {
     printf("**********************AC Contact needed*************************\n");
     if(strcmp(v1, "count") == 0)
@@ -617,6 +666,20 @@ void GetPsuInformation(char *v1)
                    i, ShmPsuData->PsuGroup[i].GroupAvailableCurrent, ShmPsuData->PsuGroup[i].GroupAvailablePower);
         }
     }
+    else if(strcmp(v1, "input") == 0)
+    {
+        for (int i = 0; i < ShmPsuData->GroupCount; i++)
+        {
+            for (byte count = 0; count < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; count++)
+            {
+                printf("gp = %d, Index = %d, volR = %d, volS = %d, volT = %d \n",
+                       i, count,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL1,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL2,
+                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL3);
+            }
+        }
+    }
     else if (strcmp(v1, "output") == 0)
     {
         for (int i = 0; i < ShmPsuData->GroupCount; i++)
@@ -624,6 +687,43 @@ void GetPsuInformation(char *v1)
             printf("Group Index = %d, OutputV = %d, OutputC = %d \n",
                    i, ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage, ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent);
         }
+
+        for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++)
+        {
+            if (!FindChargingInfoData(i, &_chargingData[0]))
+            {
+                printf ("FindChargingInfoData error\n");
+                continue;
+            }
+
+            printf("Form RB : Group Index = %d, OutputV = %f \n",
+                i, _chargingData[i]->FireChargingVoltage);
+        }
+    }
+    else if (strcmp(v1, "test") == 0)
+    {
+        int mode = atoi(v2);
+
+        if (mode >= _TEST_MODE && mode <= _TEST_MODE)
+        {
+            ShmPsuData->Work_Step = mode;
+        }
+    }
+    else if (strcmp(v1, "out") == 0)
+    {
+        float vol = atof(v2);
+        float cur = atof(v3);
+
+        if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+        {
+            if (!FindChargingInfoData(0, &_chargingData[0]))
+            {
+                printf ("FindChargingInfoData error\n");
+                return;
+            }
+            _chargingData[0]->EvBatterytargetVoltage = vol;
+            _chargingData[0]->EvBatterytargetCurrent = cur;
+        }
     }
     printf("*************************************************\n");
 }
@@ -668,18 +768,34 @@ static void get_char(char *word)
 
 void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 {
-    int _GunIndex = atoi(v1);
-    float _Voltage = atof(v2);
-    float _Current = atof(v3);
-    unsigned char PreviousSystemStatus = 0xff;
+    int _GunIndex;
+    float _Voltage;
+    float _Current;
 
+    if (strcmp(v1, "auto") == EQUAL)
+    {
+        _usingAutoRun = 0x01;
+        _GunIndex = 0;
+        _Voltage = 500;
+        _Current = (ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 1000) / _Voltage;
+    }
+    else
+    {
+        _usingAutoRun = 0x00;
+        _GunIndex = atoi(v1);
+        _Voltage = atof(v2);
+        _Current = atof(v3);
+    }
+
+    unsigned char PreviousSystemStatus = 0xff;
     if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
     {
         printf ("FindChargingInfoData error\n");
         return;
     }
 
-    printf ("ReqVoltage = %f, ReqCurrent = %f\n", _Voltage, _Current);
+    printf ("Power = %d, ReqVoltage = %f, ReqCurrent = %f\n",
+            ShmSysConfigAndInfo->SysConfig.MaxChargingPower, _Voltage, _Current);
 
     if(_Voltage > 1000 || _Voltage < 50)
     {
@@ -841,15 +957,50 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 {
                     PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
 
-                    //充電電壓電流
+                    if (_usingAutoRun == 0x00)
+                    {
+                        //充電電壓電流
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
+                    }
+                    else
+                    {
+                        _curAutoRunCount = 0;
+                        gettimeofday(&_autoTime, NULL);
+                    }
+
                     _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
-                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
-                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
                     _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;
 
                     printf ("[UnconditionalCharge - S_CHARGING]\n");
                 }
 
+                if (_usingAutoRun == 0x01)
+                {
+                    if (((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP1_TIME_START * 60 && (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP1_TIME_END * 60) ||
+                        ((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP2_TIME_START * 60 && (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP2_TIME_END * 60))
+                    {
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
+                    }
+                    else if ((GetTimeoutValue(_autoTime)) >= AUTORUN_END_TIME * 60)
+                    {
+                        _curAutoRunCount++;
+                        if (_curAutoRunCount >= AUTORUN_CYCLE_COUNT)
+                            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+                        else
+                            gettimeofday(&_autoTime, NULL);
+                    }
+                    else
+                    {
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 0;
+                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 0;
+                    }
+                }
+
+//              printf("out : vol = %f, cur = %f \n",
+//                      _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage,
+//                      _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent);
                 //ev task do this
                 _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower =
                         ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent)) / 1000);
@@ -888,6 +1039,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
                     printf ("[UnconditionalCharge - S_COMPLETE]\n");
                 }
+
+                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = 0;
                 sleep(3);
                 return;
             }
@@ -1113,7 +1266,7 @@ int main(void)
             }
 
             // 取得 PSU 資訊
-            GetPsuInformation(newString[1]);
+            GetPsuInformation(newString[1], newString[2], newString[3]);
         }
         else if (strcmp(newString[0], "cap") == 0)
         {
@@ -1127,15 +1280,30 @@ int main(void)
         {
             GetAuthorizeFlag(newString[1]);
         }
-        else if (strcmp(newString[0], "id") == 0)
+        else if (strcmp(newString[0], "relay") == 0)
         {
-            GetOrClearId(newString[1]);
+            GetRelayStatus(newString[1]);
         }
-        else if(strcmp(newString[0], "strchg") == 0)
+        else if (strcmp(newString[0], "ccid") == 0)
         {
-            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
                 strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
+            {
+                printf ("Input ccid fail.\n");
+                continue;
+            }
+            SetChargingInfoCCID(newString[1], newString[2]);
+        }
+        else if(strcmp(newString[0], "strchg") == 0)
+        {
+            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
+            if (strcmp(newString[1], "auto") == 0)
+            {
+                newString[2][0] = 0;
+                newString[3][0] = 0;
+            }
+            else if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
+                     strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
             {
                 printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
                 continue;

File diff suppressed because it is too large
+ 363 - 153
EVSE/Projects/DW30/Apps/main.c


+ 1 - 0
EVSE/Projects/DW30/Apps/timeout.h

@@ -58,4 +58,5 @@ unsigned short _connectionTimeout;
 
 // for main
 struct timeval _cmdMainPriority_time;
+struct timeval _toAverage_time;
 #endif /* TIMEOUT_H_ */

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