Browse Source

Merge branch 'DS60-120'

FolusWen 4 years ago
parent
commit
1ae9585c6d

+ 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();

+ 4 - 8
EVSE/Projects/DS60-120/Apps/Module_LcmControl.c

@@ -857,10 +857,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);
 				}
 			}
 		}
@@ -1129,10 +1126,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);
 						}
 					}
 				}
@@ -1242,6 +1236,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");

File diff suppressed because it is too large
+ 345 - 140
EVSE/Projects/DS60-120/Apps/main.c


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