Răsfoiți Sursa

2020-08-07 / Alston Lin

Actions
1. Release V0.16 files and the notes are below
Led controled by formula, gain real power on the gfd step, fix some bug and ocpp function... etc

Files
1. As follow commit history
Alston 4 ani în urmă
părinte
comite
42938a17fc

+ 16 - 2
EVSE/Projects/DS60-120/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,
 	S_CCS_PRECHARGE_ST0,
 	S_CCS_PRECHARGE_ST1,
-	S_SINGLE_RUN,
+	S_UPDATE,
 	S_NONE,
 };
 
@@ -192,4 +192,18 @@ enum _SYS_WIFI_MODE
 	_SYS_WIFI_MODE_AP = 2
 };
 
+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_ */

+ 2 - 1
EVSE/Projects/DS60-120/Apps/FactoryConfig.c

@@ -105,7 +105,7 @@ int main(int argc,char *argv[])
 	*/
 	//********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
 	//
-	strcpy((char *)SysConfig.ModelName, "DSYE601J0EE2PH");
+	strcpy((char *)SysConfig.ModelName, "DSYE601J0EW2PH");
 	strcpy((char *)SysConfig.SerialNumber, "SERIALFORRD");
 
 	memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
@@ -184,6 +184,7 @@ int main(int argc,char *argv[])
 	SysConfig.OfflineMaxChargeDuration = 0;
 	strcpy((char *) SysConfig.OcppServerURL, "");
 	strcpy((char *) SysConfig.ChargeBoxId, "");
+	SysConfig.LedInfo.Intensity = 2;
 
 	//copy default configuration to pointer
 	memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));

+ 96 - 37
EVSE/Projects/DS60-120/Apps/Module_EvComm.c

@@ -101,7 +101,7 @@ unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
 void PRINTF_FUNC(char *string, ...);
 
 void GetMaxVolAndCurMethod(byte index, float *vol, float *cur);
-void GetMaxPowerMethod(float *pow);
+void GetMaxPowerMethod(byte index, float *pow);
 unsigned long GetTimeoutValue(struct timeval _sour_time);
 
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -1786,6 +1786,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)
 	{
@@ -2206,10 +2220,17 @@ void ClearAbnormalStatus_CCS(byte gun_index)
 		memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
 		isCleanCheck = true;
 	}
-	else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023892", 6) == EQUAL &&
-			ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES)
+//	else if (strncmp((char *)_chargingData[gun_index]->EvConnAlarmCode, "023892", 6) == EQUAL &&
+//			ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES)
+//	{
+//		memcpy(code, "023892", 6);
+//		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, "023892", 6);
+		memcpy(code, "023893", 6);
 		memcpy(_chargingData[gun_index]->EvConnAlarmCode, "", 6);
 		isCleanCheck = true;
 	}
@@ -2300,6 +2321,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;
@@ -2360,7 +2383,8 @@ void ClearAbnormalStatus_CCS(byte gun_index)
 					if (strncmp(code, "023889", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsCpStatus_Error = NO;
 					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, "023892", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = NO;
+					if (strncmp(code, "023893", 6) == EQUAL) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccFailForQCA7000SetKey = NO;
 				}
 			}
 		}
@@ -2378,7 +2402,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 +2516,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 +2579,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;
@@ -2739,7 +2766,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++)
 								{
@@ -2778,8 +2805,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)
@@ -2808,7 +2835,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];
 							}
@@ -2866,7 +2893,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];
@@ -2961,14 +2988,14 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
 
 	vol = chargingData_1->MaximumChargingVoltage;
 	GetMaxVolAndCurMethod(chargingData_1->Index, &vol, &cur1);
-	GetMaxPowerMethod(&pow1);
+	GetMaxPowerMethod(chargingData_1->Index, &pow1);
 
 	pow2 = chargingData_2->AvailableChargingPower;
 	cur2 = chargingData_2->AvailableChargingCurrent;
 	vol = chargingData_2->MaximumChargingVoltage;
 
 	GetMaxVolAndCurMethod(chargingData_2->Index, &vol, &cur2);
-	GetMaxPowerMethod(&pow2);
+	GetMaxPowerMethod(chargingData_2->Index, &pow2);
 
 	if (_pow_1 != pow1 ||
 		_cur_1 != cur1 ||
@@ -3017,12 +3044,26 @@ void GetMaxVolAndCurMethod(byte index, float *vol, float *cur)
 
 	if (maxChargingCur[index] != 0 && maxChargingCur[index] <= *cur)
 		*cur = maxChargingCur[index];
+
+	if (_chargingData[index]->SystemStatus == S_CHARGING &&
+			_chargingData[index]->ChargingProfileCurrent > 0 &&
+			_chargingData[index]->ChargingProfileCurrent <= *cur)
+	{
+		*cur = _chargingData[index]->ChargingProfileCurrent;
+	}
 }
 
-void GetMaxPowerMethod(float *pow)
+void GetMaxPowerMethod(byte index, float *pow)
 {
 	if (maxChargingPow != 0 && maxChargingPow <= *pow)
 		*pow = maxChargingPow;
+
+	if (_chargingData[index]->SystemStatus == S_CHARGING &&
+			_chargingData[index]->ChargingProfilePower > 0 &&
+			_chargingData[index]->ChargingProfilePower <= *pow)
+	{
+		*pow = _chargingData[index]->ChargingProfilePower;
+	}
 }
 
 time_t GetRtcInfoForEpoch()
@@ -3150,7 +3191,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;
@@ -3207,7 +3248,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);
@@ -3267,6 +3308,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:
@@ -3308,7 +3351,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);
+					gettimeofday(&_chk_ratingPower_timeout[_index], NULL);
 				}
 					break;
 				case S_PREPARING_FOR_EVSE:
@@ -3332,7 +3375,6 @@ int main(int argc, char *argv[])
 						else if (gun_count == 2)
 							SetPresentChargingOutputCap(_chargingData[0], _chargingData[1]);
 					}
-
 					// 持續通知 Isolation 測試狀態
 					if (priorityLow == 1)
 					{
@@ -3344,9 +3386,7 @@ int main(int argc, char *argv[])
 						//if(_chargingData[_index]->GroundFaultStatus != GFD_WAIT)
 						{
 							//if ((GetTimeoutValue(_derating_time) / 1000) > 1000)
-							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 ||
@@ -3358,17 +3398,19 @@ int main(int argc, char *argv[])
 								}
 							}
 
-//							if (_result == GFD_WARNING || _result == GFD_PASS)
-//							{
-//								if ((GetTimeoutValue(_chk_ratingPower_timeout[_index]) / 1000) > 10000)
-//								{
-//									if (_chargingData[_index]->RealRatingPower == 0)
-//										_chargingData[_index]->RealRatingPower = _chargingData[_index]->AvailableChargingPower;
-//									_result = GFD_PASS;
-//								}
-//								else
-//									_result = GFD_WAIT;
-//							}
+							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);
+									//_result = GFD_PASS;
+								}
+								else
+									_result = GFD_WAIT;
+							}
 
 							SetIsolationStatus(_index, _result, _chargingData[_index]->Evboard_id);
 						}
@@ -3404,6 +3446,7 @@ int main(int argc, char *argv[])
 							}
 
 							_chargingData[_index]->PresentChargedEnergy += changingPow;
+							_chargingData[_index]->PowerConsumption += changingPow;
 							chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
 						}
 					}
@@ -3427,14 +3470,18 @@ int main(int argc, char *argv[])
 							SetPresentChargingOutputCap(_chargingData[0], _chargingData[1]);
 					}
 
+					if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
+					{
+						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]->GroundFaultStatus == GFD_FAIL)
-						{
-							SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
-						}
-
 						if(_chargingData[_index]->Type == _Type_CCS_2 &&
 							_chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
 						{
@@ -3465,11 +3512,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;

+ 240 - 117
EVSE/Projects/DS60-120/Apps/Module_InternalComm.c

@@ -55,10 +55,11 @@ 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
@@ -67,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
 
@@ -77,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 是否搭上的依據電壓
@@ -119,9 +130,6 @@ struct timeb 	_ac_endChargingTime;
 unsigned short _setFanSpeed = 0;
 float _beforeChargingTotalEnergy = 0.0;
 byte _checkLedChanged = 3;
-double _psuInputVolR = 0;
-double _psuInputVolS = 0;
-double _psuInputVolT = 0;
 
 Ver ver;
 PresentInputVoltage inputVoltage;
@@ -847,38 +855,21 @@ void GetAuxPower()
 
 void SetFanModuleSpeed()
 {
-	// 調整風扇速度要漸進式 : 500 rpm/p
-//	if (ShmFanModuleData->PresentFan1Speed != ShmFanModuleData->SetFan1Speed ||
-//			ShmFanModuleData->PresentFan2Speed != ShmFanModuleData->SetFan2Speed ||
-//			ShmFanModuleData->PresentFan3Speed != ShmFanModuleData->SetFan3Speed ||
-//			ShmFanModuleData->PresentFan4Speed != ShmFanModuleData->SetFan4Speed)
 	{
-		//printf("ShmFanModuleData->SetFan1Speed = %d \n", ShmFanModuleData->SetFan1Speed);
-
 		FanSpeed _fanSpeed;
 
-		//unsigned short speed = ShmFanModuleData->PresentFan1Speed + fanSpeedSmoothValue;
 		_setFanSpeed += fanSpeedSmoothValue;
 
-		//if (speed >= ShmFanModuleData->SetFan1Speed)
-		//	speed = ShmFanModuleData->SetFan1Speed;
 		if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
 			_setFanSpeed = ShmFanModuleData->SetFan1Speed;
+
+		//printf("_setFanSpeed = %d \n", _setFanSpeed);
 		_fanSpeed.speed[0] = _setFanSpeed;
 
-		//speed = ShmFanModuleData->PresentFan2Speed + fanSpeedSmoothValue;
-		//if (speed >= ShmFanModuleData->SetFan2Speed)
-		//	speed = ShmFanModuleData->SetFan2Speed;
 		_fanSpeed.speed[1] = _setFanSpeed;
 
-		//speed = ShmFanModuleData->PresentFan3Speed + fanSpeedSmoothValue;
-		//if (speed >= ShmFanModuleData->SetFan3Speed)
-		//	speed = ShmFanModuleData->SetFan3Speed;
 		_fanSpeed.speed[2] = _setFanSpeed;
 
-		//speed = ShmFanModuleData->PresentFan4Speed + fanSpeedSmoothValue;
-		//if (speed >= ShmFanModuleData->SetFan4Speed)
-		//	speed = ShmFanModuleData->SetFan4Speed;
 		_fanSpeed.speed[3] = _setFanSpeed;
 
 		if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed) == PASS)
@@ -1218,15 +1209,22 @@ bool IsNoneMatchLedColor()
 
 void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
 {
+	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;
 		 }
@@ -1236,10 +1234,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;
 		 }
 	}
@@ -1247,7 +1245,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;
 		}
@@ -1255,14 +1253,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;
 		}
@@ -1270,7 +1268,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;
 		}
 	}
@@ -1279,10 +1277,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)
@@ -1310,7 +1308,6 @@ int InitShareMemory()
 	int result = PASS;
 	int MeterSMId;
 
-	//creat ShmSysConfigAndInfo
 	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1325,7 +1322,7 @@ int InitShareMemory()
 		#endif
 		result = FAIL;
 	}
-	//creat ShmStatusCodeData
+
 	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1341,7 +1338,6 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
-	//creat ShmFanModuleData
 	if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1358,7 +1354,6 @@ int InitShareMemory()
 	}
 	memset(ShmFanModuleData,0,sizeof(struct FanModuleData));
 
-	//creat ShmRelayModuleData
 	if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1375,7 +1370,6 @@ int InitShareMemory()
 	}
 	memset(ShmRelayModuleData,0,sizeof(struct RelayModuleData));
 
-	//creat ShmLedModuleData
 	if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1392,7 +1386,6 @@ int InitShareMemory()
 	}
 	memset(ShmLedModuleData,0,sizeof(struct LedModuleData));
 
-	//creat ShmPsuData
 	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
@@ -1408,6 +1401,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;
 }
 
@@ -1633,7 +1641,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 &&
@@ -1646,7 +1654,8 @@ 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_GB || _chargingData[index]->Type == _Type_Chademo)
 					SetGfdConfig(index, GFD_IDLE);
@@ -1751,26 +1760,16 @@ void CheckRelayWeldingStatus(byte index)
 void GetPsuTempForFanSpeed()
 {
 	char temp = 0;
-	//double volR = 0, volS = 0, volT = 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;
-
-//			if (volR < (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL1 / 10) / 1.732)
-//				volR = (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL1 / 10) / 1.732;
-//
-//			if (volS < (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL2 / 10) / 1.732)
-//				volS = (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL2 / 10) / 1.732;
-//
-//			if (volT < (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL3 / 10) / 1.732)
-//				volT = (ShmPsuData->PsuGroup[index].PsuModule[count].InputVoltageL3 / 10) / 1.732;
 		}
 	}
 
-	//_psuInputVolR = volR; _psuInputVolS = volS; _psuInputVolT = volT;
 	ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = temp;
 
 	if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO)
@@ -1790,6 +1789,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)
@@ -1887,10 +1945,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;
@@ -1908,9 +2017,12 @@ 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;
@@ -1954,12 +2066,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;
 			}
 
@@ -1967,12 +2083,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;
 					}
 
@@ -1981,7 +2100,7 @@ void AcChargeTypeProcess()
 					break;
 				case S_PREPARNING:
 				{
-					if (_isStatusChanged)
+					if (isModeChange())
 					{
 						ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
 						ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
@@ -2002,9 +2121,10 @@ void AcChargeTypeProcess()
 					break;
 				case S_CHARGING:
 				{
-					if (_isStatusChanged)
+					if (isModeChange())
 					{
 						ftime(&_ac_startChargingTime);
+						OcppStartTransation(1);
 						ChangeStartOrStopDateTime(YES);
 						ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
 					}
@@ -2040,7 +2160,7 @@ void AcChargeTypeProcess()
 					break;
 				case S_TERMINATING:
 				{
-					if (_isStatusChanged)
+					if (isModeChange())
 					{
 						ChangeStartOrStopDateTime(NO);
 						gettimeofday(&_ac_charging_comp, NULL);
@@ -2053,10 +2173,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);
 					}
@@ -2329,71 +2455,68 @@ 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)
-				{
-//					if (ShmFanModuleData->PresentFan1Speed < MAX_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan2Speed < MAX_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan3Speed < MAX_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan4Speed < MAX_FAN_SPEED)
-//					{
-//						ShmFanModuleData->SetFan1Speed = MAX_FAN_SPEED;
-//						ShmFanModuleData->SetFan2Speed = MAX_FAN_SPEED;
-//						ShmFanModuleData->SetFan3Speed = MAX_FAN_SPEED;
-//						ShmFanModuleData->SetFan4Speed = MAX_FAN_SPEED;
-//					}
 
-					// 在還沒問到 PSU 溫度~ 還是要有個最小轉速
-					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 > 0)
-					{
-						ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-						ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-						ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-						ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-					}
-				}
-				else
-				{
-//					if (ShmFanModuleData->PresentFan1Speed > MIN_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan2Speed > MIN_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan3Speed > MIN_FAN_SPEED ||
-//						ShmFanModuleData->PresentFan4Speed > MIN_FAN_SPEED)
+//				if (isCharging)
+//				{
+////					if (ShmFanModuleData->PresentFan1Speed < MAX_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan2Speed < MAX_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan3Speed < MAX_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan4Speed < MAX_FAN_SPEED)
+////					{
+////						ShmFanModuleData->SetFan1Speed = MAX_FAN_SPEED;
+////						ShmFanModuleData->SetFan2Speed = MAX_FAN_SPEED;
+////						ShmFanModuleData->SetFan3Speed = MAX_FAN_SPEED;
+////						ShmFanModuleData->SetFan4Speed = MAX_FAN_SPEED;
+////					}
+//
+//					// 在還沒問到 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 = 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;
-					}
-				}
+//				}
+//				else
+//				{
+////					if (ShmFanModuleData->PresentFan1Speed > MIN_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan2Speed > MIN_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan3Speed > MIN_FAN_SPEED ||
+////						ShmFanModuleData->PresentFan4Speed > MIN_FAN_SPEED)
+////					{
+//						ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
+//						ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
+//						ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
+//						ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
+////					}
+//
+//					// 停止時,如溫度還是很高,則需要維持該轉速直到溫度降低
+//					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();

+ 2 - 0
EVSE/Projects/DS60-120/Apps/Module_LcmControl.c

@@ -1242,6 +1242,8 @@ int main(void)
 
 	//ChangeToOtherPage(_LCM_COMPLETE);
 	//return 0;
+	for(byte i = 0; i < 3; i++)
+		ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
 
 	while(_port != -1)
 	{

+ 317 - 101
EVSE/Projects/DS60-120/Apps/Module_PsuComm.c

@@ -350,14 +350,58 @@ 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;
+			}
+		}
+	}
+
+//	PRINTF_FUNC("group = %d, DeratingChargingCurrent = %f, RealRatingPower = %d \n",
+//					group, chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->RealRatingPower);
+
 	if (chargingInfo[group]->DeratingChargingCurrent == 0)
-		ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+	{
+		// 在還沒取得真正可輸出的電流前,依照 GFD 階段得到的真正 POWER / 模塊個數 / 車子電池最大電壓
+		if (ShmPsuData->PsuGroup[group].GroupRealOutputPower > 0 && _chargingVol > 0)
+		{
+//			printf("GroupRealOutputPower = %d, GroupPresentPsuQuantity = %d\n",
+//					ShmPsuData->PsuGroup[group].GroupRealOutputPower,
+//					ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity);
+
+			ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent =
+					((ShmPsuData->PsuGroup[group].GroupRealOutputPower / ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity) * 1000 / (int)_chargingVol) * 10;
+
+//			PRINTF_FUNC(" *1* AvailableCurrent = %d \n",
+//				ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent);
+		}
+		else
+		{
+			// 注一 : 獲取模塊最大輸出能力 (忽視 Derating 狀態),所以這邊需要限制實際可輸出的電流
+			if (ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent <= 0)
+				ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
+
+//			PRINTF_FUNC(" *2* group = %d, AvailableCurrent = %d \n",
+//				group, ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent);
+		}
+//		PRINTF_FUNC("group = %d, address = %d, AvailableCurrent = %d \n",
+//				group, address, ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent);
+	}
 	else
+	{
 		ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
+	}
 
 	ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
 	// 總和該 Group 的可輸出電流
@@ -373,7 +417,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++)
@@ -381,6 +425,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;
@@ -388,7 +433,13 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 
 	// 如果不是所有群都得到 Derating current,則先不採樣該次的 ratingCurrent
 	if (!isGetAllDeratingCurrent) _ratingcurrent = 0;
+	// 因應注一,為避免一值改變通知車子電樁最大可輸出電流所做的限制
+	// 而因為 rating value 一般都會小於模塊的最大可輸出電流
+	// 所以如果該值大於在注一所限制的輸出電流,則以此值為主
+	if (_ratingcurrent != 0) _current = _ratingcurrent;
 
+	//printf("=============== _current ==================== %d \n", _current);
+	//printf("=============== _ratingcurrent ==================== %d \n", _ratingcurrent);
 	ShmPsuData->SystemAvailableCurrent = _current;
 	ShmPsuData->SystemAvailablePower = _power;
 
@@ -399,6 +450,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))
@@ -427,16 +479,27 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 			// 2. 智能切換成均充過程
 			chargingInfo[group]->AvailableChargingCurrent =	halfCur;
 			chargingInfo[group]->AvailableChargingPower = halfPow;
+			chargingInfo[group]->RealRatingPower = gpRealPow;
 
 			if(chargingInfo[group]->DeratingChargingCurrent > 0)
 			{
-				chargingInfo[group]->RealRatingPower = (chargingInfo[group]->DeratingChargingCurrent * 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)
+				{
+					ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf;
+//					PRINTF_FUNC("group = %d, DeratingChargingCurrent = %f, RealRatingPower = %d \n",
+//								group, chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->RealRatingPower);
+				}
 			}
 			//printf("(Aver.) RealRatingPower = %d \n", chargingInfo[group]->RealRatingPower);
 		}
 	}
 	else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
 	{
+		//PRINTF_FUNC("group = %d, Final = %d \n", group, _current);
 		GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
 
 		if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
@@ -446,6 +509,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
@@ -453,13 +517,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);
 	}
 }
 
@@ -637,10 +709,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;
 		}
@@ -653,7 +726,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)
 			{
@@ -674,106 +747,223 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
 	if (isPass)
 	{
-		//PRINTF_FUNC("rating pass value = %d \n", totalCur);
+//		if (totalCur != 0)
+//				PRINTF_FUNC("group = %d, rating pass value = %d \n", group, 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)
 			{
-				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;
+
+	//unsigned short outVol = outputVol_s;
+	//unsigned short outCur = outputCur_s;
+
+	if (IsOverModuleCount(address))
+		return;
+
+	byte group = FindTargetGroup(address);
+
+	if (group == 1)
+		address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
+
+//	// PSU Group - 電壓
+//	ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outVol;
+//	// PSU Group - 電流
+//	ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outCur;
+//	// PSU Group - 能量
+//	ShmPsuData->PsuGroup[group].GroupPresentOutputPower = outVol * outCur;
+//
+//	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;
+//
+//		for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+//		{
+//			bool needtoAdd = true;
+//
+//			if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
+//				outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
+//
+////			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 (needtoAdd)
+//				outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
+//		}
+//
+//		if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A &&
+//				ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+//		{
+//			if (chargingInfo[_maxTOaver]->DividChargingCurrent != 0)
+//			{
+//				float _cur_buf = outputCur;
+//				_cur_buf /= 10;
+//				chargingInfo[_maxTOaver]->PresentChargingCurrent = _cur_buf;
+//			}
+//		}
+//
+//		// 黑白機
+//		if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
+//		{
+//			for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+//			{
+//				float _vol_buf = outputVol;
+//				float _cur_buf = outputCur;
+//
+//				// 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[group]->PresentChargingVoltage = _vol_buf;
+//
+//			_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;
+//
+//		_cur_buf /= 10;
+//		chargingInfo[group]->PresentChargingCurrent = _cur_buf;
+//	}
 
 	ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp1 = Temperature;
 	ShmPsuData->PsuGroup[group].PsuModule[address].CriticalTemp2 = Temperature;
@@ -953,6 +1143,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)
@@ -1074,6 +1266,7 @@ int main(void)
 	RefreshGetOutput(&GetPresentOutputCallback);
 	RefreshFanInfo(&GetFanSpeedCallback);
 	RefreshIavailable(&GetIavailableCallback);
+	RefreshGetOutputF(&GetPresentOutputFCallback);
 
 	// GetPresentOutputCallback & GetStatusCallback
 	AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
@@ -1138,8 +1331,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;
 					// 分別取各群模組數量
@@ -1151,6 +1342,8 @@ int main(void)
 						// 取各群模組數量
 						GetModuleCount(index);
 					}
+					PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
+							ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 
 					// 發送取得目前全部模組數量
 					GetModuleCount(SYSTEM_CMD);
@@ -1175,7 +1368,6 @@ int main(void)
 						}
 					}
 
-					_getCapDelayCount = 7;
 					gettimeofday(&_cmdSubPriority_time, NULL);
 				}
 			}
@@ -1186,30 +1378,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);
 
-						// 取版號
-						GetModuleVer(index);
-					}
-					_getCapDelayCount--;
-					gettimeofday(&_cmdSubPriority_time, NULL);
-				}
+							// 取系統總輸出能力
+							GetModuleCap(index);
 
-				// 判斷系統輸出額定功率與電流
-				if (ShmPsuData->SystemAvailablePower > 0 && ShmPsuData->SystemAvailableCurrent > 0 &&
-						_getCapDelayCount <= 0)
-				{
-					PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
+							// 取版號
+							GetModuleVer(index);
+						}
+					}
+					else
+					{
+						// 判斷系統輸出額定功率與電流
+						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;
@@ -1247,7 +1451,7 @@ int main(void)
 						//GetStatus(index);
 
 						// 取得模塊輸出額定電流能力
-						GetModuleIavailable(index);
+						//GetModuleIavailable(index);
 
 						if (chargingInfo[index]->SystemStatus == S_CHARGING)
 						{
@@ -1301,12 +1505,18 @@ 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 (time > 1000)
 						{
 							if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
 								evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
@@ -1321,7 +1531,7 @@ int main(void)
 								evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
 							{
 								evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
-								PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
+								PRINTF_FUNC("groupIndex = %d, ev need cur = %f, evse output cur = %f \n", groupIndex,
 									(chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
 									(chargingInfo[groupIndex]->PresentChargingCurrent * 10));
 							}
@@ -1351,6 +1561,7 @@ int main(void)
 							else
 							{
 								chargingInfo[groupIndex]->DividChargingCurrent = 0;
+								chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 0;
 							}
 
 							if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
@@ -1459,8 +1670,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);
@@ -1505,7 +1718,7 @@ 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);
@@ -1866,6 +2079,9 @@ int main(void)
 					{
 						// 取系統總輸出能力
 						GetModuleCap(index);
+
+						// 取各群輸出電壓電流 (float)
+						GetModuleOutputF(index);
 					}
 
 					gettimeofday(&_cmdSubPriority_time, NULL);
@@ -1880,7 +2096,7 @@ int main(void)
 					SetDirModulePresentOutput(connector_1[_groupCount_1],
 						(chargingInfo[0]->EvBatterytargetVoltage * 10),
 						(chargingInfo[0]->EvBatterytargetCurrent * 10),
-						_switch);
+						_switch, _switch);
 				}
 
 				for (byte _groupCount_2 = 0; _groupCount_2 < conn_2_count; _groupCount_2++)
@@ -1888,7 +2104,7 @@ int main(void)
 					SetDirModulePresentOutput(connector_2[_groupCount_2],
 						(chargingInfo[0]->EvBatterytargetVoltage * 10),
 						(chargingInfo[0]->EvBatterytargetCurrent * 10),
-						_switch);
+						_switch, _switch);
 				}
 			}
 				break;

+ 0 - 1
EVSE/Projects/DS60-120/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;
 

+ 37 - 27
EVSE/Projects/DS60-120/Apps/OutputTask.c

@@ -203,27 +203,27 @@ void GetInputString()
 
 void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
 {
-	printf("address = %d, Iavail = %d, Vext = %d \n", address, Iavail, 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_FUNC("***Output Value and Temp*** address = %d, Vol = %d, Cur = %d, Pow = %d, Temp = %d \n",
-//			address, outputVol, outputCur, outputPower, 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);
+	//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);
+//	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,
@@ -268,20 +268,20 @@ int main(void)
 	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)
+//	{
+//		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();
@@ -308,20 +308,30 @@ int main(void)
 			{
 				case CHARGING_MODE_START:
 				{
-					if (!isOpen)
+					//if (!isOpen)
 					{
-						SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
-						FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
+						//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);
+					//PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10);
 				}
 					break;
 				case CHARGING_MODE_TERMINATING:
 				{
-					if (isOpen)
+					//if (isOpen)
 					{
-						SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
-						FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+						SetDirModulePresentOutput(0,
+							VOLTAGE * 10,
+							CURRENT * 10,
+							0x00,
+							0x01);
+						//SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+						//FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
 					}
 				}
 					break;

+ 123 - 22
EVSE/Projects/DS60-120/Apps/ReadCmdline.c

@@ -41,14 +41,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 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;
@@ -227,7 +239,7 @@ 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)
@@ -423,7 +435,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;
 }
 
@@ -435,16 +447,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()
@@ -472,6 +485,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);
@@ -650,6 +676,18 @@ void GetPsuInformation(char *v1, char *v2, char *v3)
 			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)
 	{
@@ -719,18 +757,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)
     {
@@ -777,7 +831,6 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     		}
     		break;
 
-
     		case S_PREPARNING:
     		{
         	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
@@ -792,8 +845,6 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	    }
     		    //main 會在此階段判斷以下資料跳到下一個 state
     		    //用來得知 AC 是否有搭上 (搭上模組的資訊才會出來) 因為每次  AC_Contactor
-
-
     		    //ShmPsuData->SystemPresentPsuQuantity;
     		    //ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity;
     		    //ShmPsuData->PsuGroup[gun_index].GroupAvailablePower;
@@ -840,11 +891,9 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     		        //EV done
     		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARING_FOR_EVSE;
     		    }
-
     		}
     		break;
 
-
     		case S_PREPARING_FOR_EVSE:
     		{
         	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
@@ -897,15 +946,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);
@@ -943,6 +1027,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
         	        printf ("[UnconditionalCharge - S_COMPLETE]\n");
         	    }
+
+        	    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = 0;
         	    sleep(3);
         	    return;
     		}
@@ -1182,14 +1268,29 @@ 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], "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], "-1") == 0 || strcmp(newString[1], "") == 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");

Fișier diff suprimat deoarece este prea mare
+ 345 - 140
EVSE/Projects/DS60-120/Apps/main.c


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff