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

Merge branch 'AW-CCS' of https://git.phihong.com.tw:30000/System_Integration/CSU3_AM335x into AW-CCS

8009 3 жил өмнө
parent
commit
de1b1b6c9e

+ 173 - 161
EVSE/Modularization/WebService.c

@@ -1060,169 +1060,155 @@ int main(int argc, char *argv[]) {
 			DEBUG_INFO("WebServiceConfig update OK");
 		#endif
 	}
-	if (argc == 2) {	//init share memory for test
-		if (strcmp(argv[1], "aaa") == 0) {
-			//struct SysConfigData 	SysConfig;
-		//system
-		ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity=1;
-		ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity=1;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.ModelName, "DO0E362001D1P0D");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SerialNumber, "SerialNumber");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SystemId, "1234567890");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SystemDateTime, "2019-12-31 23:59:59");
-		ShmSysConfigAndInfo->SysConfig.AcPhaseCount=1;
-		ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy=0;
-		ShmSysConfigAndInfo->SysInfo.FactoryConfiguration=0;
-		ShmSysConfigAndInfo->SysConfig.AuthorisationMode=0;
-		ShmSysConfigAndInfo->SysConfig.DefaultLanguage=0;
-		ShmSysConfigAndInfo->SysInfo.InputVoltageR=0;
-		ShmSysConfigAndInfo->SysInfo.InputVoltageS=0;
-		ShmSysConfigAndInfo->SysInfo.InputVoltageT=0;
-		ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed=0;
-		ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed=0;
-		ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian=0;
-		ShmSysConfigAndInfo->SysConfig.RatingCurrent=100;
-		ShmSysConfigAndInfo->SysConfig.PsuAcInputType=0;
-		ShmSysConfigAndInfo->SysInfo.AuxPower5V=0;
-		ShmSysConfigAndInfo->SysInfo.AuxPower12V=0;
-		ShmSysConfigAndInfo->SysInfo.AuxPower24V=0;
-		ShmSysConfigAndInfo->SysInfo.AuxPower48V=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.LcmHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.LcmFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuSecFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.AuxPwrHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.AuxPwrFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, "");
-		strcpy((char *)&ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, "");
-		ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp=0;
-		ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp=0;
-		ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp=0;
-		ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp=0;
-		ShmSysConfigAndInfo->SysConfig.AcPlugInTimes=0;
-		ShmSysConfigAndInfo->SysConfig.GbPlugInTimes=0;
-		ShmSysConfigAndInfo->SysConfig.Ccs1PlugInTime=0;
-		ShmSysConfigAndInfo->SysConfig.Ccs2PlugInTimes=0;
-		ShmSysConfigAndInfo->SysConfig.ChademoPlugInTimes=0;
-		// strcpy((char *)&ShmPsuData->PsuVersion[0].FwPrimaryVersion, "DC 9.01");
-		// strcpy((char *)&ShmPsuData->PsuVersion[1].FwPrimaryVersion, "DC 9.02");
-		// strcpy((char *)&ShmPsuData->PsuVersion[0].FwSecondVersion, "PFC 9.02");
-		// strcpy((char *)&ShmPsuData->PsuVersion[1].FwSecondVersion, "PFC 9.03");
 
-		//charging
-		ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy=0;
-		ShmSysConfigAndInfo->SysConfig.MaxChargingPower=0;
-		ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent= 0;
-		ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent= 0;
-		ShmSysConfigAndInfo->SysConfig.MaxChargingDuration=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0], "111");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[1], "222");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[2], "333");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[3], "444");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[4], "555");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[5], "666");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[6], "777");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[7], "888");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[8], "999");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[9], "aaa");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.UserId, "UserId");
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingVoltage=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingCurrent=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingPower=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargedEnergy=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargedDuration=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].RemainChargingDuration=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatteryMaxVoltage=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterytargetVoltage=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterySoc=0;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].SystemStatus=1;
-		ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterytargetCurrent=1;
-		//network
-		ShmSysConfigAndInfo->SysInfo.InternetConn=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.FtpServer,"");
-		ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient=1;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,"192.168.1.10");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress,"255.255.255.0");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress,"192.168.1.1");
-		ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient=1;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthMacAddress,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress,"192.168.0.10");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress,"255.255.255.0");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthGatewayAddress,"192.168.0.1");
-		ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode=1;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword,"");
-		ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi=0;
-		ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpServer=0;
-		ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMacAddress,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiIpAddress,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSubmaskAddress,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiGatewayAddress,"");
-		ShmSysConfigAndInfo->SysConfig.AthInterface.WifiNetworkConn=1;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn,"");
-		ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid,"");
-		ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus=0;
-		ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress,"");
-		//backend
-		ShmSysConfigAndInfo->SysConfig.BackendConnTimeout=300;
-		ShmSysConfigAndInfo->SysConfig.OfflinePolicy=0;
-		ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy=0;
-		ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration=0;
-		ShmSysConfigAndInfo->SysInfo.OcppConnStatus=0;
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.ChargeBoxId,"");
-		strcpy((char *)&ShmSysConfigAndInfo->SysConfig.chargePointVendor,"Phihong");
-
-		ShmSysConfigAndInfo->SysInfo.FirmwareUpdate=0;
-		struct SysConfigData 	SysConfig;
-		memcpy(&SysConfig, &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData));
-		StoreUsrConfigData(&SysConfig);
-		
-		// struct PsuModuleVer 	PsuData;
-		// memcpy(&PsuData, &ShmPsuData->PsuVersion, sizeof(struct PsuModuleVer));
-		// StoreUsrConfigData(&PsuData);
+	if (argc == 2)
+	{	//init share memory for test
+		if (strcmp(argv[1], "aaa") == 0)
+		{
+			//struct SysConfigData 	SysConfig;
+			//system
+			ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity=1;
+			ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity=1;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.ModelName, "DO0E362001D1P0D");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SerialNumber, "SerialNumber");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SystemId, "1234567890");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.SystemDateTime, "2019-12-31 23:59:59");
+			ShmSysConfigAndInfo->SysConfig.AcPhaseCount=1;
+			ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy=0;
+			ShmSysConfigAndInfo->SysInfo.FactoryConfiguration=0;
+			ShmSysConfigAndInfo->SysConfig.AuthorisationMode=0;
+			ShmSysConfigAndInfo->SysConfig.DefaultLanguage=0;
+			ShmSysConfigAndInfo->SysInfo.InputVoltageR=0;
+			ShmSysConfigAndInfo->SysInfo.InputVoltageS=0;
+			ShmSysConfigAndInfo->SysInfo.InputVoltageT=0;
+			ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed=0;
+			ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed=0;
+			ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian=0;
+			ShmSysConfigAndInfo->SysConfig.RatingCurrent=100;
+			ShmSysConfigAndInfo->SysConfig.PsuAcInputType=0;
+			ShmSysConfigAndInfo->SysInfo.AuxPower5V=0;
+			ShmSysConfigAndInfo->SysInfo.AuxPower12V=0;
+			ShmSysConfigAndInfo->SysInfo.AuxPower24V=0;
+			ShmSysConfigAndInfo->SysInfo.AuxPower48V=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.LcmHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.LcmFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.PsuSecFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.AuxPwrHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.AuxPwrFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, "");
+			strcpy((char *)&ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, "");
+			ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp=0;
+			ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp=0;
+			ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp=0;
+			ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp=0;
+			ShmSysConfigAndInfo->SysConfig.AcPlugInTimes=0;
+			ShmSysConfigAndInfo->SysConfig.GbPlugInTimes=0;
+			ShmSysConfigAndInfo->SysConfig.Ccs1PlugInTime=0;
+			ShmSysConfigAndInfo->SysConfig.Ccs2PlugInTimes=0;
+			ShmSysConfigAndInfo->SysConfig.ChademoPlugInTimes=0;
+			// strcpy((char *)&ShmPsuData->PsuVersion[0].FwPrimaryVersion, "DC 9.01");
+			// strcpy((char *)&ShmPsuData->PsuVersion[1].FwPrimaryVersion, "DC 9.02");
+			// strcpy((char *)&ShmPsuData->PsuVersion[0].FwSecondVersion, "PFC 9.02");
+			// strcpy((char *)&ShmPsuData->PsuVersion[1].FwSecondVersion, "PFC 9.03");
+
+			//charging
+			ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy=0;
+			ShmSysConfigAndInfo->SysConfig.MaxChargingPower=0;
+			ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent= 0;
+			ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent= 0;
+			ShmSysConfigAndInfo->SysConfig.MaxChargingDuration=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[0], "111");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[1], "222");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[2], "333");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[3], "444");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[4], "555");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[5], "666");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[6], "777");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[7], "888");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[8], "999");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[9], "aaa");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.UserId, "UserId");
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingVoltage=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingCurrent=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargingPower=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargedEnergy=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].PresentChargedDuration=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].RemainChargingDuration=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatteryMaxVoltage=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterytargetVoltage=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterySoc=0;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].SystemStatus=1;
+			ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].EvBatterytargetCurrent=1;
+			//network
+			ShmSysConfigAndInfo->SysInfo.InternetConn=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.FtpServer,"");
+			ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient=1;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,"192.168.1.10");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress,"255.255.255.0");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress,"192.168.1.1");
+			ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient=1;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthMacAddress,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress,"192.168.0.10");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress,"255.255.255.0");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthGatewayAddress,"192.168.0.1");
+			ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode=1;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword,"");
+			ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi=0;
+			ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpServer=0;
+			ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMacAddress,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiIpAddress,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSubmaskAddress,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiGatewayAddress,"");
+			ShmSysConfigAndInfo->SysConfig.AthInterface.WifiNetworkConn=1;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn,"");
+			ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid,"");
+			ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus=0;
+			ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress,"");
+			//backend
+			ShmSysConfigAndInfo->SysConfig.BackendConnTimeout=300;
+			ShmSysConfigAndInfo->SysConfig.OfflinePolicy=0;
+			ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy=0;
+			ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration=0;
+			ShmSysConfigAndInfo->SysInfo.OcppConnStatus=0;
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.ChargeBoxId,"");
+			strcpy((char *)&ShmSysConfigAndInfo->SysConfig.chargePointVendor,"Phihong");
+
+			ShmSysConfigAndInfo->SysInfo.FirmwareUpdate=0;
+			struct SysConfigData 	SysConfig;
+			memcpy(&SysConfig, &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData));
+			StoreUsrConfigData(&SysConfig);
+
+			// struct PsuModuleVer 	PsuData;
+			// memcpy(&PsuData, &ShmPsuData->PsuVersion, sizeof(struct PsuModuleVer));
+			// StoreUsrConfigData(&PsuData);
 
-		#ifdef SystemLogMessage
-		DEBUG_INFO("WebService initial OK");
-		#endif
-		}
-		if (strcmp(argv[1], "log") == 0) {
-			unsigned char			ModelName[64];;
-			unsigned char			SerialNo[64];;
-			memcpy(ModelName,ShmSysConfigAndInfo->SysConfig.ModelName,ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName));
-			printf("%s", ModelName);
-			memcpy(SerialNo,ShmSysConfigAndInfo->SysConfig.SerialNumber,ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber));
-			printf("%s", SerialNo);
-			time_t tt = time(0); //獲取當前時間
-			int year,month;
-			char cmd[512];
-			struct tm *pst = localtime(&tt); //把time_t類型轉換為struct tm類型
-			year = pst->tm_year + 1900;
-			month = pst->tm_mon + 1;
-//			sprintf(cmd,"cp /mnt/*%s*%s*.zip /var/www/log.zip",ModelName,SerialNo);
-			if(system("exec /root/logPackTools 'log'")==0){
-				system(cmd);
-			}
+			#ifdef SystemLogMessage
+			DEBUG_INFO("WebService initial OK");
+			#endif
 		}
 
-		if (strcmp(argv[1], "button") == 0) {
+		if (strcmp(argv[1], "button") == 0)
+		{
 			unsigned char			Button1;
 			unsigned char			Button2;
 			unsigned char			EmergencyButton;
@@ -1243,12 +1229,38 @@ int main(int argc, char *argv[]) {
 			printf("%s\n", json_object_to_json_string(jobj));
 		}
 
-		if (strcmp(argv[1], "restart") == 0) {
+		if (strcmp(argv[1], "restart") == 0)
+		{
 			system("exec /usr/bin/run_evse_restart.sh");
 		}
 	}
+
+	if(strcmp(argv[1], "log") == 0)
+	{
+		char cmd[512];
+
+		if((argc == 3) && isdigit(*argv[2]))
+		{
+			sprintf(cmd, "exec /root/logPackTools 'log' %s", argv[2]);
+		}
+		else
+		{
+			sprintf(cmd, "exec /root/logPackTools 'log'");
+		}
+
+		if(system(cmd) == 0)
+		{
+			DEBUG_INFO("Log pack success.\n");
+		}
+		else
+		{
+			DEBUG_INFO("Log pack fail.\n");
+		}
+	}
+
 	//upgrade firmware
-	if ((argc == 3) & (strcmp(argv[1], "upgrade") == 0)) {
+	if ((argc == 3) & (strcmp(argv[1], "upgrade") == 0))
+	{
 		struct json_object *jobj;
 		struct json_object *Result;
 		struct json_object *Message;

+ 5 - 1
EVSE/Projects/AW-CCS/Apps/main.c

@@ -3675,6 +3675,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend watch dog timeout task restart.\n");
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
@@ -3690,6 +3692,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend20 watch dog timeout task restart.\n");
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
@@ -4356,7 +4360,7 @@ void checkRfidAuthrize()
 		{
 			if(ocpp_get_auth_conf() ||
 			   (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
-			   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0))
+			   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[0][TMR_IDX_AUTH]) > 2000))
 			  )
 			{
 				if(ocpp_get_auth_result(NO) ||

+ 25 - 13
EVSE/Projects/AW-ChargeLab/Apps/main.c

@@ -21,7 +21,7 @@
 #define TMR_IDX_LOGPPRINTOUT			2
 #define TMR_IDX_PROFILE_PREPARE			3
 #define TMR_IDX_PWN_CHANGE				4
-#define TMR_IDX_5						5
+#define TMR_IDX_CHECK_TASK					5
 #define TMR_IDX_6						6
 #define TMR_IDX_7						7
 #define TMR_IDX_8						8
@@ -2972,6 +2972,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend watch dog timeout task restart.\n");
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
@@ -2987,6 +2989,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend20 watch dog timeout task restart.\n");
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
@@ -3571,16 +3575,24 @@ int main(void)
 		//==========================================
 		ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status();
 
-		//==========================================
-		// Check task processing
-		//==========================================
-		if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
-			checkTask();
+		//==============================================
+		// Period check for 10 seconds
+		//==============================================
+		if(DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10000)
+		{
+			//==============================================
+			// Check task processing
+			//==============================================
+			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
+				checkTask();
 
-		//==========================================
-		// Check connection timeout specification
-		//==========================================
-		checkConnectionTimeout();
+			//==============================================
+			// Check connection timeout specification
+			//==============================================
+			checkConnectionTimeout();
+
+			ftime(&startTime[0][TMR_IDX_CHECK_TASK]);
+		}
 
 		//==========================================
 		// Something need run in Idle mode
@@ -3955,7 +3967,7 @@ int main(void)
 							case START_METHOD_RFID:
 								if((ocpp_get_auth_conf()) ||
 								   (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
-								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
+								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)))
 								{
 									if(ocpp_get_auth_result(gun_index) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
@@ -4177,7 +4189,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||
@@ -4525,7 +4537,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||

+ 25 - 13
EVSE/Projects/AW-Regular/Apps/main.c

@@ -21,7 +21,7 @@
 #define TMR_IDX_LOGPPRINTOUT			2
 #define TMR_IDX_PROFILE_PREPARE			3
 #define TMR_IDX_PWN_CHANGE				4
-#define TMR_IDX_5						5
+#define TMR_IDX_CHECK_TASK					5
 #define TMR_IDX_6						6
 #define TMR_IDX_7						7
 #define TMR_IDX_8						8
@@ -2972,6 +2972,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend watch dog timeout task restart.\n");
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
@@ -2987,6 +2989,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend20 watch dog timeout task restart.\n");
 				ShmOCPP20Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend20");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend20 > /dev/null") != 0)
@@ -3571,16 +3575,24 @@ int main(void)
 		//==========================================
 		ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status();
 
-		//==========================================
-		// Check task processing
-		//==========================================
-		if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
-			checkTask();
+		//==============================================
+		// Period check for 10 seconds
+		//==============================================
+		if(DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10000)
+		{
+			//==============================================
+			// Check task processing
+			//==============================================
+			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
+				checkTask();
 
-		//==========================================
-		// Check connection timeout specification
-		//==========================================
-		checkConnectionTimeout();
+			//==============================================
+			// Check connection timeout specification
+			//==============================================
+			checkConnectionTimeout();
+
+			ftime(&startTime[0][TMR_IDX_CHECK_TASK]);
+		}
 
 		//==========================================
 		// Something need run in Idle mode
@@ -3955,7 +3967,7 @@ int main(void)
 							case START_METHOD_RFID:
 								if((ocpp_get_auth_conf()) ||
 								   (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
-								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
+								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)))
 								{
 									if(ocpp_get_auth_result(gun_index) ||
 									   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) ||
@@ -4177,7 +4189,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||
@@ -4525,7 +4537,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||

+ 23 - 9
EVSE/Projects/DO360/Apps/Config.h

@@ -11,7 +11,7 @@
 
 typedef unsigned char			    byte;
 
-
+
 #define MODE_BOOT					0
 #define MODE_IDLE					1
 #define MODE_AUTHORIZING			2
@@ -171,8 +171,11 @@ enum _MODULE_PSU_WORK_STEP
 {
 	INITIAL_START 		= 		0,
 	GET_PSU_COUNT 		= 		1,
-	GET_SYS_CAP			=		2,
-	BOOTING_COMPLETE 	= 		3,
+	Get_PSU_LOCATION    =       2,
+	Get_PSU_VERSION     =       3,
+	PSU_COUNT_CONFIRM   =       4,
+	GET_SYS_CAP			=		5,
+	BOOTING_COMPLETE 	= 		6,
 
 	_WORK_CHARGING 		= 		10,
 
@@ -310,7 +313,8 @@ typedef union
         unsigned int SecondRelayBoardEnable:1;      // 0: second relay disable,     1: second relay enable
         unsigned int StandardLedIndication:1;       // 0: no led indication,        1: enable standard led indication
         unsigned int E4YOULedIndication:1;          // 0: no led indication,        1: enable e4you led indication
-        unsigned int res:22;
+        unsigned int BackendEnable:1;               // 0: backend disable,          1: backend enable
+        unsigned int res:21;
     }bits;
 }SystemControl;
 
@@ -331,7 +335,12 @@ typedef union
     unsigned int CtrlValue;
     struct
     {
-        unsigned int res:32;
+        unsigned int MsgMain:1;                     // 0: no effect,                1: enable debug message in main
+        unsigned int MsgPrimaryComm:1;              // 0: no effect,                1: enable debug message in primary comm
+        unsigned int MsgPsu:1;                      // 0: no effect,                1: enable debug message in psu
+        unsigned int MsgEvComm:1;                   // 0: no effect,                1: enable debug message in ev comm
+        unsigned int MsgInternalComm:1;             // 0: no effect,                1: enable debug message in internal comm
+        unsigned int res:27;
     }bits;
 }DebugControl;
 
@@ -519,9 +528,11 @@ typedef union
         // MasterCtrlValue
         unsigned int AlreadyInChargingMode:1;                   // 0: no effect,                1: system status ever enter charging mode
         unsigned int ExtendAvailable:1;                         // 0: no effect,                1: extend capability is available
-        unsigned int NeedCurrentBalanceCheck:1;                 // 0: no effect,                1: need to current balance
+        unsigned int NeedCurrentBalance:1;                      // 0: no effect,                1: need to current balance
         unsigned int OutputCurrentStable:1;                     // 0: no effect,                1: output current is stable
-        unsigned int MasterCtrlRes:28;
+        unsigned int ReachMaxCurrentDemand:1;                   // 0: no effect,                1: reach ev max current demand
+        unsigned int ReachMaxStageCurrent:1;                    // 0: no effect,                1: reach ev max stage current
+        unsigned int MasterCtrlRes:26;
 
         // StopChargingCtrlValue
         unsigned int StopChargingRequest:1;                     // 0: no effect,                1: master need to stop
@@ -555,15 +566,18 @@ typedef union
 
         // SlaveCtrlValue
         unsigned int SlaveChargingRequest:1;                    // 0: no effect,                1: request slave to charging after power off
+        unsigned int CheckSlaveReady:1;                         // 0: no effect,                1: check if slave is ready
+        unsigned int WaitSlaveReady:1;                          // 0: no effect,                1: wait slave is ready
         unsigned int SlavePowerOffRequest:1;                    // 0: no effect,                1: request slave to power off
         unsigned int SlavePowerOffConfirmed:1;                  // 0: no effect,                1: slave power off confirmed
-        unsigned int SlaveCtrlRes:29;
+        unsigned int SlaveCtrlRes:27;
     }bits;
 }PsuGroupControl;
 
 typedef struct
 {
-    unsigned short          Quantity;
+    unsigned char           Quantity;
+    unsigned char           RealQuantity;
     unsigned char           Member[MAX_GROUP_QUANTITY];         // record slave group index
 }PsuGroupPartner;
 

+ 119 - 94
EVSE/Projects/DO360/Apps/FactoryConfig.c

@@ -39,6 +39,7 @@
 #define OUTPUT_FILE			0x02
 
 struct SysConfigData 			SysConfig;
+struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 
 int StoreLogMsg(const char *fmt, ...);
 
@@ -68,14 +69,64 @@ int StoreLogMsg(const char *fmt, ...)
 	return rc;
 }
 
+int runShellCmd(const char *cmd)
+{
+    int result = FAIL;
+    char buf[256];
+    FILE *fp;
+
+    fp = popen(cmd, "r");
+    if(fp != NULL)
+    {
+        while(fgets(buf, sizeof(buf), fp) != NULL)
+        {
+            StoreLogMsg("%s\n", buf);
+        }
+
+        result = PASS;
+    }
+    pclose(fp);
+
+    return result;
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+    int result = PASS;
+    int MeterSMId;
+
+    //creat ShmSysConfigAndInfo
+    if((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+        StoreLogMsg("shmget ShmSysConfigAndInfo NG\n");
+
+        result = FAIL;
+    }
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        StoreLogMsg("shmat ShmSysConfigAndInfo NG\n");
+
+        result = FAIL;
+     }
+    else
+    {
+
+    }
+
+    return result;
+}
+
 void helpOutput(void)
 {
-	printf("Usage: Module_FactoryConfig [OPTION]...\r\n\r\n");
-	printf("Generate factory default configuration value\r\n\r\n");
-	printf("OPTION:\r\n");
-	printf("	-a Write to file(/mnt) & flash\r\n");
-	printf("	-f Write to file(/mnt)\r\n");
-	printf("	-m Write to flash\r\n");
+    printf("Usage: Module_FactoryConfig [OPTION]...\r\n\r\n");
+    printf("Generate factory default configuration value\r\n\r\n");
+    printf("OPTION:\r\n");
+    printf("    -a Write to file(/mnt) & flash\r\n");
+    printf("    -f Write to file(/mnt)\r\n");
+    printf("    -m Write to flash\r\n");
 }
 
 /**************************************************************************************/
@@ -85,7 +136,7 @@ void helpOutput(void)
 int main(int argc,char *argv[])
 {
 	unsigned char outType=0;
-	unsigned int i,Chk, MtdBlockSize=0x600000;
+	unsigned int i,Chk, MtdBlockSize=0x300000;
 	unsigned char *ptr;
 	int fd,wrd;
 
@@ -105,23 +156,30 @@ int main(int argc,char *argv[])
 	*/
 	//********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
 	//
-    if (argc == 4)
-    {
-        strcpy((char *)SysConfig.ModelName, argv[2]);
-        strcpy((char *)SysConfig.SerialNumber, argv[3]);
-    }
-    else
+    time_t t = time(NULL);
+    struct tm tm = *localtime(&t);
+
+    // Initial Share Memory
+    if(InitShareMemory() == FAIL)
     {
+        StoreLogMsg("InitShareMemory NG\n");
+
+        //strcpy((char*)SysConfig.ModelName, "");
+        //strcpy((char*)SysConfig.SerialNumber, "");
         strcpy((char *)SysConfig.ModelName, "DOYC182000D2AD");
         strcpy((char *)SysConfig.SerialNumber, "NeedSetupSN");
+        sleep(5);
     }
+    else
+    {
+        memcpy((char*)SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.ModelName, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName));
+        memcpy((char*)SysConfig.SerialNumber, ShmSysConfigAndInfo->SysConfig.SerialNumber, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber));
 
-	memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
-
-	strcat((char *)SysConfig.SystemId, (char *)SysConfig.ModelName);
-	strcat((char *)SysConfig.SystemId, (char *)SysConfig.SerialNumber);
+        StoreLogMsg("InitShareMemory OK.\n");
+    }
 
-	strcpy((char *)SysConfig.SystemDateTime, "");
+    sprintf((char*)SysConfig.SystemId, "%s%s", SysConfig.ModelName, SysConfig.SerialNumber);
+    sprintf((char*)SysConfig.SystemDateTime, "%d-%d-%d %d:%d:%d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 	SysConfig.AuthorisationMode = AUTH_MODE_ENABLE;
 	SysConfig.DefaultLanguage = 0;
 	SysConfig.RfidCardNumEndian = 0;
@@ -154,7 +212,7 @@ int main(int argc,char *argv[])
 	SysConfig.Eth1Interface.EthDhcpClient = 0;
 	strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.100.1");
 	strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
-	strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
+	strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.100.254");
 	SysConfig.AthInterface.WifiMode = 0;
 	SysConfig.TelecomInterface.TelcomEnabled = 0;
 	strcpy((char *) SysConfig.AthInterface.WifiSsid, "");
@@ -198,12 +256,12 @@ int main(int argc,char *argv[])
 	memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));
 
 	//calculate CRC
-	Chk=0;
-	for(i=0;i<(MtdBlockSize-4);i++)
-	{
-		Chk+=*(ptr+i);
-	}
-	memcpy(	ptr+MtdBlockSize-4,&Chk,4);
+    Chk = 0;
+    for(i = ARRAY_SIZE(SysConfig.CsuBootLoadFwRev); i < (MtdBlockSize - 4); i++)
+    {
+        Chk += *(ptr + i);
+    }
+    memcpy(ptr + MtdBlockSize - 4, &Chk, 4);
 
 	/*
 	* Parameter process
@@ -244,82 +302,49 @@ int main(int argc,char *argv[])
 	/*
 	 * Configuration bin file generate
 	*/
-	if((outType&OUTPUT_FILE)>0)
-	{
-		fd = open("/mnt/FactoryDefaultConfig.bin", O_RDWR | O_CREAT);
-		if (fd < 0)
-		{
-			StoreLogMsg("[FactoryConfig]main: open /mnt/FactoryDefaultConfig.bin NG");
-			free(ptr);
-			return 0;
-		}
-		wrd=write(fd, ptr, MtdBlockSize);
-		close(fd);
-		if(wrd<MtdBlockSize)
-		{
-			StoreLogMsg("write /mnt/FactoryDefaultConfig.bin NG\r\n");
-			free(ptr);
-			return 0;
-		}
-		StoreLogMsg("FactoryConfig write to file in /mnt OK.\r\n");
-	}
+    fd = open("/mnt/FactoryDefaultConfig.bin", O_RDWR | O_CREAT | O_TRUNC);
+    if(fd < 0)
+    {
+        StoreLogMsg("[FactoryConfig]main: open /mnt/FactoryDefaultConfig.bin NG");
+        free(ptr);
+        return 0;
+    }
+    wrd = write(fd, ptr, MtdBlockSize);
+    close(fd);
+    if(wrd < MtdBlockSize)
+    {
+        StoreLogMsg("write /mnt/FactoryDefaultConfig.bin NG\r\n");
+        free(ptr);
+        return 0;
+    }
+    StoreLogMsg("FactoryConfig write to file in /mnt OK.\r\n");
 
 	/*
 	* Flash memory write
 	*/
-	if((outType&OUTPUT_FLASH)>0)
+	if((outType & OUTPUT_FLASH) > 0)
 	{
-		// Save factory default setting value to flash factory default setting block
-		fd = open("/dev/mtdblock12", O_RDWR);
-		if (fd < 0)
-		{
-			StoreLogMsg("open /dev/mtdblock12 NG\r\n");
-			free(ptr);
-			return 0;
-		}
-		wrd=write(fd, ptr, MtdBlockSize);
-		close(fd);
-		if(wrd<MtdBlockSize)
-		{
-			StoreLogMsg("write /dev/mtdblock12 NG\r\n");
-			free(ptr);
-			return 0;
-		}
+        // Save factory default setting value to flash setting block
+        StoreLogMsg("Erase /dev/mtd10.\n");
+        runShellCmd("flash_erase /dev/mtd10 0 0");
+        StoreLogMsg("Write /dev/mtd10.\n");
+        runShellCmd("nandwrite -p /dev/mtd10 /mnt/FactoryDefaultConfig.bin");
 
-		// Save factory default setting value to flash backup setting block
-		fd = open("/dev/mtdblock11", O_RDWR);
-		if (fd < 0)
-		{
-			StoreLogMsg("open /dev/mtdblock11 NG\r\n");
-			free(ptr);
-			return 0;
-		}
-		wrd=write(fd, ptr, MtdBlockSize);
-		close(fd);
-		if(wrd<MtdBlockSize)
-		{
-			StoreLogMsg("write /dev/mtdblock11 NG\r\n");
-			free(ptr);
-			return 0;
-		}
+        // Save factory default setting value to flash backup setting block
+        StoreLogMsg("Erase /dev/mtd11.\n");
+        runShellCmd("flash_erase /dev/mtd11 0 0");
+        StoreLogMsg("Write /dev/mtd11.\n");
+        runShellCmd("nandwrite -p /dev/mtd11 /mnt/FactoryDefaultConfig.bin");
 
-		// Save factory default setting value to flash setting block
-		fd = open("/dev/mtdblock10", O_RDWR);
-		if (fd < 0)
-		{
-			StoreLogMsg("open /dev/mtdblock10 NG\r\n");
-			free(ptr);
-			return 0;
-		}
-		wrd=write(fd, ptr, MtdBlockSize);
-		close(fd);
-		if(wrd<MtdBlockSize)
-		{
-			StoreLogMsg("write /dev/mtdblock10 NG\r\n");
-			free(ptr);
-			return 0;
-		}
-		StoreLogMsg("FactoryConfig write to flash OK\r\n");
+        // Save factory default setting value to flash factory default setting block
+        StoreLogMsg("Erase /dev/mtd12.\n");
+        runShellCmd("flash_erase /dev/mtd12 0 0");
+        StoreLogMsg("Write /dev/mtd12.\n");
+        runShellCmd("nandwrite -p /dev/mtd12 /mnt/FactoryDefaultConfig.bin");
+
+        system("rm -f /mnt/FactoryDefaultConfig.bin");
+
+        StoreLogMsg("FactoryConfig write to flash OK\r\n");
 	}
 
 	free(ptr);

+ 956 - 0
EVSE/Projects/DO360/Apps/InfyGroup_PsuCommObj.c

@@ -0,0 +1,956 @@
+/*
+ * Infypwr_PsuCommObj.c
+ *
+ *  Created on: 2019年11月26日
+ *      Author: 7564
+ */
+
+#include "InfyGroup_PsuCommObj.h"
+
+#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
+#define NO		0
+#define YES		1
+
+#define DEBUG_LIB						1
+
+void PRINTF_LIB_FUNC(char *string, ...);
+float IEEE_754_to_float(const byte raw[4]);
+
+//================================================
+// Private function
+//================================================
+void PRINTF_LIB_FUNC(char *string, ...)
+{
+	if (DEBUG_LIB)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
+float IEEE_754_to_float(const byte raw[4])
+{
+    float fValue = 0;
+    byte *pbyte = (byte *)&fValue;
+
+    *(pbyte + 0) = raw[3];
+    *(pbyte + 1) = raw[2];
+    *(pbyte + 2) = raw[1];
+    *(pbyte + 3) = raw[0];
+
+    return fValue;
+}
+
+//================================================
+// Callback function
+//================================================
+void RefreshStatus(void *func)
+{
+	return_status = func;
+}
+
+void RefreshModuleCount(void *func)
+{
+	return_module_count = func;
+}
+
+void RefreshAvailableCap(void *func)
+{
+	return_available_cap = func;
+}
+
+void RefreshFwVersion(void *func)
+{
+	return_fw_version = func;
+}
+
+void RefreshInputVol(void *func)
+{
+	return_input_vol = func;
+}
+
+void RefreshGetOutput(void *func)
+{
+	return_get_output = func;
+}
+
+void RefreshGetOutputF(void *func)
+{
+	return_get_output_float = func;
+}
+
+void RefreshMisInfo(void *func)
+{
+	return_mis_info = func;
+}
+
+void RefreshIavailable(void *func)
+{
+	return_iavail_info = func;
+}
+
+void AutoMode_RefreshOutputAndTemp(void *func)
+{
+	return_output_temp = func;
+}
+
+void AutoMode_RefreshModuleStatus(void *func)
+{
+	return_module_status = func;
+}
+
+void AutoMode_RefreshModuleInput(void *func)
+{
+	return_module_input = func;
+}
+
+//================================================
+// CANBUS initialization
+//================================================
+int InitCanBus()
+{
+	int 					s0,nbytes;
+	struct timeval			tv;
+	struct ifreq 			ifr0;
+	struct sockaddr_can		addr0;
+
+	system("/sbin/ip link set can1 down");
+	system("/sbin/ip link set can1 type can bitrate 500000 restart-ms 100");
+	system("/sbin/ip link set can1 up");
+
+	s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 10000;
+   	if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct	timeval)) < 0)
+	{
+		#ifdef SystemLogMessage
+   		PRINTF_LIB_FUNC("Set SO_RCVTIMEO NG");
+		#endif
+	}
+	nbytes=40960;
+	if (setsockopt(s0, SOL_SOCKET,  SO_RCVBUF, &nbytes, sizeof(int)) < 0)
+	{
+		#ifdef SystemLogMessage
+		PRINTF_LIB_FUNC("Set SO_RCVBUF NG");
+		#endif
+	}
+	nbytes=40960;
+	if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0)
+	{
+		#ifdef SystemLogMessage
+		PRINTF_LIB_FUNC("Set SO_SNDBUF NG");
+		#endif
+	}
+	nbytes=40960;
+
+   	strcpy(ifr0.ifr_name, "can1" );
+	ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */
+	addr0.can_family = AF_CAN;
+	addr0.can_ifindex = ifr0.ifr_ifindex;
+	bind(s0, (struct sockaddr *)&addr0, sizeof(addr0));
+	return s0;
+}
+
+//================================================
+// Receive Cmd from canbus
+//================================================
+void ReceiveDataFromCanBus()
+{
+    int nbytes;
+    struct can_frame frame;
+    PwrFrame *PwrFrameMsg;
+    byte group, address;
+
+    while(1)
+	{
+        memset(&frame, 0, sizeof(struct can_frame));
+        nbytes = read(CanFd, &frame, sizeof(struct can_frame));
+
+        if (nbytes > 0)
+        {
+            PwrFrameMsg = (PwrFrame *)&frame.can_id;
+            address = PwrFrameMsg->InfyBits.SourceAddress;
+
+            if(PwrFrameMsg->InfyBits.DestinationAddress != NEXTON_ADD)
+            {
+                switch (PwrFrameMsg->InfyBits.CmdValue)
+                {
+                    // 0x01
+                    case PSU_RCmd_SysOutputVolCur_F:
+                    {
+                        group = address;
+                        byte vol[4], cur[4];
+                        memcpy(vol, frame.data, 4);
+                        memcpy(cur, frame.data + 4, 4);
+
+                        float _Vol = IEEE_754_to_float(vol);
+                        float _Cur = IEEE_754_to_float(cur);
+
+                        return_get_output_float(group, _Vol, _Cur);
+                    }
+                        break;
+
+                    // 0x02
+                    case PSU_RCmd_SysModuleCount:
+                    {
+                        // 回傳模組數量
+                        byte count = 0;
+                        count = frame.data[2];
+
+                        return_module_count(address, count);
+                    }
+                        break;
+
+                    // 0x04
+                    case PSU_RCmd_ModuleStatus:
+                    {
+                        // 回傳模組組號及狀態
+                        byte SN = address;
+                        group = frame.data[2];
+                        char temp = frame.data[4];
+                        unsigned int status = (frame.data[5] << 16) | (frame.data[6] << 8) | frame.data[7];
+
+                        return_status(group, SN, temp, status);
+                    }
+                        break;
+
+                    // 0x06
+                    case PSU_RCmd_ModuleInputVoltage:
+                    {
+                        // 回傳三向輸入電壓
+                        short abVol = ((frame.data[0] << 8) + frame.data[1]) / 10;
+                        short bcVol = ((frame.data[2] << 8) + frame.data[3]) / 10;
+                        short caVol = ((frame.data[4] << 8) + frame.data[5]) / 10;
+
+                        return_input_vol(address, abVol, bcVol, caVol);
+                    }
+                        break;
+
+                    // 0x07
+                    case PSU_RCmd_ModuleVersion:
+                    {
+                        short dcSwVer = ((frame.data[0] << 8) + frame.data[1]);
+                        short pfcSwVer = ((frame.data[2] << 8) + frame.data[3]);
+                        short hwVer = ((frame.data[4] << 8) + frame.data[5]);
+
+                        return_fw_version(address, dcSwVer, pfcSwVer, hwVer);
+                    }
+                        break;
+
+                    // 0x08
+                    case PSU_RCmd_SysOutputVolCur:
+                    {
+                        // 回傳當前輸出電壓電流
+                        int outputVol = ((frame.data[0] << 24) + (frame.data[1] << 16) + (frame.data[2] << 8) + frame.data[3]) / 100;
+                        int outputCur = ((frame.data[4] << 24) + (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7]) / 100;
+
+                        // outputVol unit: 1mV > 0.1V
+                        // outputCur unit: 1mA > 0.1A
+                        return_get_output(address, outputVol, outputCur);
+                    }
+                        break;
+
+                    // 0x0A
+                    case PSU_RCmd_ModuleCapability:
+                    {
+                        // 回傳輸出能力 : 最大電壓、最小電壓、最大電流、額定功率
+                        short maxVol = ((frame.data[0] << 8) + frame.data[1]) * 10;
+                        short minVol = ((frame.data[2] << 8) + frame.data[3]) * 10;
+                        short maxCur = (frame.data[4] << 8) + frame.data[5];
+                        short totalPow = ((frame.data[6] << 8) + frame.data[7]) / 10;
+
+                        // maxVol unit: 1V > 0.1V
+                        // minVol unit: 1V > 0.1V
+                        // maxCur unit: 0.1A
+                        // totalPow unit: 0.01kW > 0.1kW
+                        return_available_cap(address, maxVol, minVol, maxCur, totalPow);
+                    }
+                        break;
+
+                    // 0x0B
+                    case PSU_RCmd_ModuleBarcode:
+                    {
+                        // 回傳BarCode
+                    }
+                        break;
+
+                    // 0x0C
+                    case PSU_RCmd_ModuleIAvailable:
+                    {
+                        // 回傳降載後的電流
+                        unsigned short vextVol = ((frame.data[0] << 8) + frame.data[1]);
+                        unsigned short iAvailCur = ((frame.data[2] << 8) + frame.data[3]);
+
+                        return_iavail_info(address, iAvailCur, vextVol);
+                    }
+                        break;
+
+                    // 0x0E
+                    case PSU_RCmd_ModuleMiscInfo:
+                    {
+                        byte value[4], type = 0;
+                        unsigned short MiscType = (frame.data[0] << 8) | frame.data[1];
+                        float MiscInfoValue = 0;
+                        memcpy(value, frame.data + 4, sizeof(value));
+                        MiscInfoValue = IEEE_754_to_float(value);
+
+                        if(MiscType == FAN_SPEED_CMD)
+                        {
+                            type = 1;
+                        }
+                        if(MiscType == TEMP_DC_CMD)
+                        {
+                            type = 2;
+                        }
+                        if(MiscType == TEMP_PFC_CMD)
+                        {
+                            type = 3;
+                        }
+
+                        return_mis_info(address, MiscInfoValue, type);
+                    }
+                        break;
+
+                    // 0x13
+                    case PSU_WCmd_ModuleWalkIn:
+                    {
+
+                    }
+                        break;
+                }
+            }
+            else
+            {
+                switch(PwrFrameMsg->NextonBits.CmdValue)
+                {
+                    case Nexton_PSU_DcOutputValue:
+                    {
+                        short outputVol = ((frame.data[0] << 8) + frame.data[1]);
+                        short outputCur = ((frame.data[2] << 8) + frame.data[3]);
+                        short outputPow = ((frame.data[4] << 8) + frame.data[5]);
+                        char temp = frame.data[6];
+
+                        return_output_temp(address, outputVol, outputCur, outputPow, temp);
+                    }
+                        break;
+
+                    case Nexton_PSU_StatusEvent:
+                    {
+                        byte isErr =  (frame.data[0] >> 0) & 0x01;
+                        byte status = (frame.data[0] >> 1) & 0x01;
+                        byte err1 = frame.data[2];
+                        byte err2 = frame.data[3];
+                        byte err3 = frame.data[4];
+                        byte err4 = frame.data[5];
+
+                        return_module_status(address, isErr, status, err1, err2, err3, err4);
+                    }
+                        break;
+
+                    case Nexton_PSU_AcInputValue:
+                    {
+                        short vR = ((frame.data[0] << 8) + frame.data[1]);
+                        short vS = ((frame.data[2] << 8) + frame.data[3]);
+                        short vT = ((frame.data[4] << 8) + frame.data[5]);
+
+                        // vR, vS, vT unit: 0.1V
+                        return_module_input(address, vR, vS, vT);
+                    }
+                        break;
+                }
+            }
+		}
+		else
+			usleep(10000);
+	}
+}
+
+//================================================
+// Private Function
+//================================================
+void SendCmdToPsu(int cmd, byte *data, byte dataLen)
+{
+    PwrFrame PwrFrameMsg;
+    struct can_frame frame;
+
+    //設定 CANBSU 2.0B 長封包
+    PwrFrameMsg.PwrMessage = cmd | 0x80000000;
+
+    frame.can_id = PwrFrameMsg.PwrMessage;
+    frame.can_dlc = dataLen;
+    memcpy(frame.data, data, dataLen);
+
+    write(CanFd, &frame, sizeof(struct can_frame));
+    // 群命令才 delay
+    if (PwrFrameMsg.InfyBits.DestinationAddress == INFY_ADD_BROADCAST)
+    {
+        usleep(CMD_DELAY_TIME);
+    }
+}
+
+bool InitialCommunication()
+{
+    CanFd = InitCanBus();
+
+    if(CanFd < 0)
+    {
+        PRINTF_LIB_FUNC("Init can bus fail.\n");
+        return false;
+    }
+
+    recFork = fork();
+    if(recFork == 0)
+    {
+        ReceiveDataFromCanBus();
+    }
+
+    return true;
+}
+
+//================================================
+// API Function
+//================================================
+void SwitchPower(byte group, byte value)
+{
+    byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModulePowerOnOff;
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+    // 1 : 關機
+    // 0 : 開機
+    data[0] = value;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SleepMode(byte group, byte value)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSleepMode;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// 1 : 休眠
+	// 0 : 起床
+	data[0] = value;
+
+	if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void FlashLed(byte group, byte value)
+{
+    byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleFlashLed;
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+    // 1 : 閃爍
+    // 0 : 正常
+    data[0] = value;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void PresentOutputVol(byte group, int voltage, int current)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_SetOutput;
+
+	int Vol = voltage * 100;
+	int Cur = current * 100;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	// 輸出電壓
+	data[0] = (Vol >> 24) & 0xFF;
+	data[1] = (Vol >> 16) & 0xFF;
+	data[2] = (Vol >> 8) & 0xFF;
+	data[3] = Vol & 0xFF;
+	// 輸出電流
+	data[4] = (Cur >> 24) & 0xFF;
+	data[5] = (Cur >> 16) & 0xFF;
+	data[6] = (Cur >> 8) & 0xFF;
+	data[7] = Cur & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+// voltage: unit: 1mV
+// current: unit: 1mA
+void SetModuleOutputVol(byte group, int voltage, int current)
+{
+    byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSetOutput;
+
+    int Vol = voltage;
+    int Cur = current;
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+
+    // 輸出電壓
+    data[0] = (Vol >> 24) & 0xFF;
+    data[1] = (Vol >> 16) & 0xFF;
+    data[2] = (Vol >> 8) & 0xFF;
+    data[3] = Vol & 0xFF;
+    // 輸出電流
+    data[4] = (Cur >> 24) & 0xFF;
+    data[5] = (Cur >> 16) & 0xFF;
+    data[6] = (Cur >> 8) & 0xFF;
+    data[7] = Cur & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void FanNoiseInfo(byte group, byte value)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSetMiscInfo;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	// 風扇低噪音
+    data[0] = ((SetMiscInfo_FanMode >> 8) & 0xFF);
+    data[1] = (SetMiscInfo_FanMode & 0xFF);
+    data[7] = value;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SetWalkInConfig(byte group, byte enable, byte sec)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleWalkIn;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	unsigned short _Sec = sec * 100;
+
+	// Walk-in mode enable
+	data[0] = enable;
+	// Walk-in time (default == 5s)
+	data[6] = (_Sec >> 8) & 0xFF;
+	data[7] = _Sec & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay)
+{
+}
+
+void SetDipSwitchMode()
+{
+    byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_DipSwitchMode;
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+    data[0] = 0x01;
+
+    PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    PwrFrameMsg.InfyBits.DestinationAddress = INFY_ADD_BROADCAST;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+/**********************************************************************************/
+/***                                                                            ***/
+/***                                   Get                                      ***/
+/***                                                                            ***/
+/**********************************************************************************/
+void GetStatus(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleStatus;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetFanSpeed(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	data[0] = (FAN_SPEED_CMD >> 8) & 0xFF;
+	data[1] = FAN_SPEED_CMD & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetDcTemperature(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	data[0] = (TEMP_DC_CMD >> 8) & 0xFF;
+	data[1] = TEMP_DC_CMD & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetPfcTemperature(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	data[0] = (TEMP_PFC_CMD >> 8) & 0xFF;
+	data[1] = TEMP_PFC_CMD & 0xFF;
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleCount(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysModuleCount;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleVer(byte group)
+{
+	// 無系統廣播功能
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleVersion;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleCap(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleCapability;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleBarCode(byte group)
+{
+	// 無系統廣播功能
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleBarcode;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleInput(byte group)
+{
+	// 無系統廣播功能
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleInputVoltage;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleIavailable(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleIAvailable;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleOutput(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysOutputVolCur;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleOutputF(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysOutputVolCur_F;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+/**********************************************************************************/
+/***                                                                            ***/
+/***                                 Upgrate                                    ***/
+/***                                                                            ***/
+/**********************************************************************************/
+void ChangePsuBaudrate(short baudrate)
+{
+}
+
+
+
+
+

+ 242 - 0
EVSE/Projects/DO360/Apps/InfyGroup_PsuCommObj.h

@@ -0,0 +1,242 @@
+/*
+ * Infypwr_PsuCommObj.h
+ *
+ *  Created on: 2019年11月26日
+ *      Author: 7564
+ */
+
+#ifndef INFYPWR_PSUCOMMOBJ_H_
+#define INFYPWR_PSUCOMMOBJ_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <linux/wireless.h>
+#include <linux/can.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+
+#include 	<stdbool.h>
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<errno.h>
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<math.h>
+
+#define SYSTEM_CMD                  0x3F
+#define DEVICE_NO_SINGLE_MODULE     0x0A
+#define DEVICE_NO_GROUP_MODULE      0x0B
+#define INFY_ADD_BROADCAST          0x3F
+#define INFY_ADD_CSU                0xF0
+#define NEXTON_ADD                  0xFF
+
+#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
+#define CMD_DELAY_TIME 		25000
+#define FAN_SPEED_CMD		0x1201
+#define TEMP_DC_CMD			0x1107
+#define TEMP_PFC_CMD		0x1108
+
+typedef unsigned char       byte;
+typedef unsigned short      word;
+typedef unsigned int        unit;
+
+int 						CanFd;
+pid_t 						recFork;
+
+typedef union
+{
+    unsigned int PwrMessage;
+    struct
+    {
+        unsigned int SourceAddress:8;                   // source address
+        unsigned int DestinationAddress:8;              // destination address
+        unsigned int CmdValue:6;                        // command value
+        unsigned int DeviceValue:4;                     // 0x0A: for module command, 0x0B group command
+        unsigned int Error:3;                           // error code
+        unsigned int res:3;
+    }InfyBits;
+    struct
+    {
+        unsigned int SourceAddress:8;                   // source address
+        unsigned int DestinationAddress:8;              // destination address
+        unsigned int CmdValue:13;                       // command value
+        unsigned int res:3;
+    }NextonBits;
+}PwrFrame;
+
+enum PSU_POWER_CMD
+{
+	PSU_POWER_ON = 		0,
+	PSU_POWER_OFF = 	1,
+};
+
+enum PSU_SLEEP_MODE_CMD
+{
+	PSU_SLEEP_MODE_WAKE_UP = 	0,
+	PSU_SLEEP_MODE_SLEEP = 		1,
+};
+
+enum PSU_FLASH_CMD
+{
+	PSU_FLASH_NORMAL = 		0,
+	PSU_FLASH_ON = 			1,
+};
+
+enum PSU_FAN_NOISE_CMD
+{
+    PSU_FAN_NOISE_BY_POWER =        0xA0,       // power poriority mode
+    PSU_FAN_NOISE_BY_DENOISE =      0xA1,       // denoise mode
+    PSU_FAN_NOISE_BY_QUIET =        0xA2,       // quiet mode
+};
+
+typedef enum
+{
+    Infy_MsgErr_Normal          = 0x00,
+    Infy_MsgErr_Reserved1       = 0x01,
+    Infy_MsgErr_CmdInvalid      = 0x02,
+    Infy_MsgErr_DataInvalid     = 0x03,
+    Infy_MsgErr_InvalidAdd      = 0x04,
+    Infy_MsgErr_Reserved2       = 0x05,
+    Infy_MsgErr_Reserved3       = 0x06,
+    Infy_MsgErr_StartProcess    = 0x07,
+}InfyMessageError;
+
+typedef enum
+{
+    PSU_RCmd_SysOutputVolCur_F      = 0x01,
+    PSU_RCmd_SysModuleCount         = 0x02,
+    PSU_RCmd_ModuleOutputVolCur_F   = 0x03,     // no use
+    PSU_RCmd_ModuleStatus           = 0x04,
+    PSU_RCmd_ModuleInputVoltage     = 0x06,
+    PSU_RCmd_ModuleVersion          = 0x07,
+    PSU_RCmd_SysOutputVolCur        = 0x08,
+    PSU_RCmd_ModuleOutputVolCur     = 0x09,     // no use
+    PSU_RCmd_ModuleCapability       = 0x0A,
+    PSU_RCmd_ModuleBarcode          = 0x0B,
+    PSU_RCmd_ModuleIAvailable       = 0x0C,
+    PSU_RCmd_ModuleMiscInfo         = 0x0E,
+    PSU_WCmd_ModuleSetMiscInfo      = 0x0F,
+    PSU_WCmd_ModuleWalkIn           = 0x13,
+    PSU_WCmd_ModuleFlashLed         = 0x14,
+    PSU_WCmd_ModuleSetGroup         = 0x16,
+    PSU_WCmd_ModuleSleepMode        = 0x19,
+    PSU_WCmd_ModulePowerOnOff       = 0x1A,
+    PSU_WCmd_SetOutput              = 0x1B,
+    PSU_WCmd_ModuleSetOutput        = 0x1C,
+    PSU_WCmd_DipSwitchMode          = 0x1F,
+}InfyPwrCommand;
+
+typedef enum
+{
+    Nexton_PSU_ChargingRequest      = 0x1801,
+    Nexton_PSU_DcOutputValue        = 0x1901,
+    Nexton_PSU_StatusEvent          = 0x1902,
+    Nexton_PSU_AcInputValue         = 0x1903,
+}NextonPwrCommand;
+
+typedef enum
+{
+    GetMiscInfo_DcTemperature       = 0x1107,
+    GetMiscInfo_PfcTemperature      = 0x1108,
+    GetMiscInfo_FanSpeed            = 0x1201,
+}GetMiscInfoCommand;
+
+typedef enum
+{
+    SetMiscInfo_FanMode             = 0x1113,
+    SetMiscInfo_FanSpeed            = 0x1201,
+    SetMiscInfo_CurrentLimit        = 0x1205,
+    SetMiscInfo_SendTemperature     = 0x1301,
+}SetMiscInfoCommand;
+
+/*Initialization*/
+bool InitialCommunication();
+
+/*Set Cmd*/
+void SwitchPower(byte group, byte value);
+void SleepMode(byte group, byte value);
+void FlashLed(byte group, byte value);
+void PresentOutputVol(byte group, int voltage, int current);
+void SetModuleOutputVol(byte group, int voltage, int current);
+void FanNoiseInfo(byte group, byte value);
+void SetWalkInConfig(byte group, byte enable, byte sec);
+void SetDipSwitchMode();
+
+/*Ver : 9.06 used*/
+void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay);
+/*Get Cmd*/
+void GetStatus(byte group);
+void GetFanSpeed(byte group);
+void GetDcTemperature(byte group);
+void GetPfcTemperature(byte group);
+void GetFanSpeed(byte group);
+void GetModuleCount(byte group);
+void GetModuleVer(byte group);
+void GetModuleCap(byte group);
+void GetModuleBarCode(byte group);
+void GetModuleInput(byte group);
+void GetModuleIavailable(byte group);
+void GetModuleOutput(byte group);
+void GetModuleOutputF(byte group);
+
+/*Upgrade*/
+void ChangePsuBaudrate(short baudrate);
+
+/* Callback Function */
+void RefreshStatus(void *func);
+void (*return_status)(byte group, byte address, byte temp, int status);
+
+void RefreshModuleCount(void *func);
+void (*return_module_count)(byte group, byte count);
+
+void RefreshAvailableCap(void *func);
+void (*return_available_cap)(byte address, short maxVol, short minVol, short maxCur, short totalPow);
+
+void RefreshFwVersion(void *func);
+void (*return_fw_version)(byte address, short dcSwVer, short pfcSwVer, short hwVer);
+
+void RefreshInputVol(void *func);
+void (*return_input_vol)(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3);
+
+void RefreshGetOutput(void *func);
+void (*return_get_output)(byte address, unsigned short outVol, unsigned short outCur);
+
+void RefreshGetOutputF(void *func);
+void (*return_get_output_float)(byte group, float outVol, float outCur);
+
+void RefreshMisInfo(void *func);
+void (*return_mis_info)(byte address, unsigned int fanSpeed, byte type);
+
+void RefreshIavailable(void *func);
+void (*return_iavail_info)(byte address, unsigned short Iavail, unsigned short Vext);
+
+/*Test mode used*/
+void AutoMode_RefreshOutputAndTemp(void *func);
+void (*return_output_temp)(byte address, unsigned short outputVol,
+		unsigned short outputCur, unsigned short outputPower, unsigned char Temperature);
+
+void AutoMode_RefreshModuleStatus(void *func);
+void (*return_module_status)(byte address, unsigned char isErr, unsigned char status,
+		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4);
+
+void AutoMode_RefreshModuleInput(void *func);
+void (*return_module_input)(byte address, unsigned short inputR,
+		unsigned short inputS, unsigned short inputT);
+/* Callback Function end */
+#endif /* INFYPWR_PSUCOMMOBJ_H_ */

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

@@ -13,7 +13,7 @@ Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 all: CopyFile apps Clean
 #apps: Module_CSU Module_EvComm Module_EventLogging Module_InternalComm Module_LcmControl Module_PrimaryComm Module_PsuComm 
 # ReadCmdline kill.sh
-apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask UnsafetyOutputTool FactoryConfigApp OtherTools
+apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask InfyGroup_PsuCommObj PsuCommTask ReadCmdlineTask UnsafetyOutputTool FactoryConfigApp OtherTools
 
 MainTask:
 	rm -f *.o
@@ -56,10 +56,16 @@ PrimaryCommTask:
 	$(CC) -o Module_PrimaryComm Module_PrimaryComm.o PrimaryComm.o
 	cp -f Module_PrimaryComm ../Images/root	
 
+InfyGroup_PsuCommObj:
+	rm -f libInfyGroup_PsuCommObj.a
+	$(CC) -D $(Project) -O0 -g3 -Wall -c -fmessage-length=0 -o InfyGroup_PsuCommObj.o InfyGroup_PsuCommObj.c
+	$(AR) -r libInfyGroup_PsuCommObj.a InfyGroup_PsuCommObj.o
+	rm -f InfyGroup_PsuCommObj.o
+
 PsuCommTask:
 	rm -f Module_PsuComm; 
-	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PsuComm.o Module_PsuComm.c
-	$(CC) -o Module_PsuComm Module_PsuComm.o ../../../Modularization/libInfypwr_PsuCommObj.a
+	$(CC) -D $(Project) -includeInfyGroup_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PsuComm.o Module_PsuComm.c
+	$(CC) -o Module_PsuComm Module_PsuComm.o libInfyGroup_PsuCommObj.a
 	cp -f Module_PsuComm ../Images/root	
 	
 ReadCmdlineTask:

+ 91 - 86
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -53,6 +53,7 @@
 
 struct SysConfigAndInfo				*ShmSysConfigAndInfo;
 ChargerInfoData                     *ShmChargerInfo;
+struct ChargingInfoData             *chargingInfo[CONNECTOR_QUANTITY];
 
 //struct WARNING_CODE_INFO            LastWarningInfo[GENERAL_GUN_QUANTITY];
 
@@ -149,61 +150,9 @@ int InitShareMemory()
 		result = FAIL;
 	 }
 	else
-	{}
-	/*
-	//creat ShmStatusCodeData
-	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
 	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
-		#endif
-		result = FAIL;
-	}
-	else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
-		#endif
-		result = FAIL;
-	}
-	else
-	{}
-
-	//creat ShmOCPP16Data
-	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data),  0777)) < 0)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmOCPP16Data NG");
-		#endif
-		result = FAIL;
-	}
-	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmat ShmOCPP16Data NG");
-		#endif
-		result = FAIL;
-	}
-	else
-	{}
 
-	//creat ShmPsuData
-	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmPsuData NG \n");
-		#endif
-		result = FAIL;
 	}
-	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmat ShmPsuData NG \n");
-		#endif
-		result = FAIL;
-	 }
-	memset(ShmPsuData,0,sizeof(struct PsuData));
-	*/
 
     if ((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData), 0777)) < 0)
     {
@@ -919,6 +868,12 @@ unsigned char ConnectorQuantityTypeParsing(unsigned char *modelName, unsigned ch
 	return quantity;
 }
 
+void SendPacket(int socket, struct PACKET_STRUCTURE *packet)
+{
+    //ShowSocketData(packet);
+    send(socket, packet, packet->Header.len + 4, 0);
+}
+
 void ModelNameResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
 {
 	struct PACKET_STRUCTURE sendBuffer;
@@ -931,7 +886,7 @@ void ModelNameResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned cha
 	sendBuffer.Payload.reg = _Reg_Dispenser_Model_Name;
 	sendBuffer.Payload.data[0] = result;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void ConnectorIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result, unsigned char dispenserIndex)
@@ -948,7 +903,7 @@ void ConnectorIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
 	sendBuffer.Payload.data[1] = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorID[0];
 	sendBuffer.Payload.data[2] = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorID[1];
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 // more message for debug
@@ -1022,7 +977,7 @@ void PowerCabinetStatusResponse(int socket, struct PACKET_STRUCTURE *packet, uns
         PRINTF_FUNC("%s", str);
     }
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void DispenserStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1037,7 +992,7 @@ void DispenserStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
 	sendBuffer.Payload.reg = _Reg_Dispenser_Status;
 	sendBuffer.Payload.data[0] = result;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 struct ChargingCapabilityResponse ConnectorCapability[GENERAL_GUN_QUANTITY];
@@ -1093,7 +1048,8 @@ void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
         (ConnectorCapability[packet->Header.id - 1].MaxOuputCurrent / 10) != (current / 10) ||
         (ConnectorCapability[packet->Header.id - 1].MaxOuputPower / 10) != (power / 10))
 	{
-	    PRINTF_FUNC("Connector %d Capability Voltage: %d, Current: %d, Power: %d", packet->Header.id, (int)(voltage), (int)(current), (int)(power));
+        PRINTF_FUNC("Connector %d Capability Voltage: %4d.%d V, Current: %3d.%d A, Power: %d kW", packet->Header.id,
+            (voltage / 10), (voltage % 10), (current / 10), (current % 10), (power / 10));
 	}
 
 	if(ConnectorCapability[packet->Header.id - 1].Currency != currency ||
@@ -1138,7 +1094,7 @@ void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
     sendBuffer.Payload.data[18] = ((account >> 8) & 0xFF);
     sendBuffer.Payload.data[19] = (account & 0xFF);
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void ChargingTargetResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1153,7 +1109,7 @@ void ChargingTargetResponse(int socket, struct PACKET_STRUCTURE *packet, unsigne
 	sendBuffer.Payload.reg = _Reg_Charging_Target;
 	sendBuffer.Payload.data[0] = result;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex, unsigned char result)
@@ -1176,7 +1132,7 @@ void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
         sendBuffer.Header.len += length;
     }
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 void PlugInStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1191,7 +1147,7 @@ void PlugInStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned
 	sendBuffer.Payload.reg = _Reg_Plug_In_Status;
 	sendBuffer.Payload.data[0] = result;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void ConnectorStateResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1206,7 +1162,7 @@ void ConnectorStateResponse(int socket, struct PACKET_STRUCTURE *packet, unsigne
 	sendBuffer.Payload.reg = _Reg_Connector_State;
 	sendBuffer.Payload.data[0] = result;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void UserIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1222,7 +1178,7 @@ void UserIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char r
 	sendBuffer.Payload.data[0] = result == _DAS_Wait ? _R_NG : _R_OK;
 	sendBuffer.Payload.data[1] = result == _DAS_Allowed ? _PS_Permitted : _PS_NotPermitted;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void ChargingPermissionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1238,7 +1194,7 @@ void ChargingPermissionResponse(int socket, struct PACKET_STRUCTURE *packet, uns
 	sendBuffer.Payload.data[0] = result == _DAS_Wait ? _R_NG : _R_OK;
 	sendBuffer.Payload.data[1] = result == _DAS_Allowed ? _PS_Permitted : _PS_NotPermitted;
 
-	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+	SendPacket(socket, &sendBuffer);
 }
 
 void AddMiscCommand(struct PACKET_STRUCTURE *packet, struct MISC_COMMAND *misc)
@@ -1438,7 +1394,7 @@ void MiscControlResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
         }
     }
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 void WriteCsuVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1453,7 +1409,7 @@ void WriteCsuVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
     sendBuffer.Payload.reg = _Reg_Report_Csu_Version;
     sendBuffer.Payload.data[0] = result;
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 void WriteOtherVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1468,22 +1424,36 @@ void WriteOtherVersionResponse(int socket, struct PACKET_STRUCTURE *packet, unsi
     sendBuffer.Payload.reg = _Reg_Report_Other_Version;
     sendBuffer.Payload.data[0] = result;
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 void WriteChargingInfoResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
 {
     struct PACKET_STRUCTURE sendBuffer;
 
+    unsigned short voltage = 0, current = 0;
+
+#if 0
+    // for safety test
+    unsigned char gun = packet->Header.id - 1;
+    voltage = (unsigned short)(chargingInfo[gun]->PresentChargingVoltage * 10);
+    current = (unsigned short)(chargingInfo[gun]->PresentChargingCurrent * 10);
+    voltage -= ((current * 8 * 10) / 10000);
+#endif
+
     memset(&sendBuffer, 0x00, sizeof(sendBuffer));
     sendBuffer.Header.se = packet->Header.se;
     sendBuffer.Header.id = packet->Header.id;
     sendBuffer.Header.op = _Header_Response;
-    sendBuffer.Header.len = 2;
+    sendBuffer.Header.len = 6;
     sendBuffer.Payload.reg = _Reg_Charging_Info;
     sendBuffer.Payload.data[0] = result;
+    sendBuffer.Payload.data[1] = (voltage >> 8) & 0xFF;
+    sendBuffer.Payload.data[2] = (voltage >> 0) & 0xFF;
+    sendBuffer.Payload.data[3] = (current >> 8) & 0xFF;
+    sendBuffer.Payload.data[4] = (current >> 0) & 0xFF;
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 int GetChargerSystemId(char *id)
@@ -1548,7 +1518,7 @@ void ChargerSystemIdResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
         //PRINTF_FUNC("Dispenser %d Read System Id: %s", dispenserIndex + 1, ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
     }
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 void WriteWaitPlugInResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
@@ -1563,7 +1533,7 @@ void WriteWaitPlugInResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
     sendBuffer.Payload.reg = _Reg_WaitPlugIn;
     sendBuffer.Payload.data[0] = result;
 
-    send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
+    SendPacket(socket, &sendBuffer);
 }
 
 BOOL FindConnectorID(unsigned char dispenserIndex, unsigned char id)
@@ -1713,6 +1683,7 @@ void SetConnectorID(unsigned char dispenserIndex, unsigned char quantity)
 		currentQuantity++;
 		ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorID[i] = currentQuantity;
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[currentQuantity - 1].Enable = true;
+		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[currentQuantity - 1].GeneralChargingData.Index = currentQuantity - 1;
 	}
 }
 
@@ -1923,8 +1894,8 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage != targetVol ||
 				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetCurrent != targetCur)
 			{
-				PRINTF_FUNC("Connector %d Target Voltage: %d, Current: %d",
-                    packet->Header.id, (int)(targetVol * 10), (int)(targetCur * 10));
+                PRINTF_FUNC("Connector %d Target Voltage: %d V, Current: %d A",
+                    packet->Header.id, (int)(targetVol), (int)(targetCur));
 			}
 
 			ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage = targetVol;
@@ -2017,11 +1988,21 @@ BOOL ConnectorStateHandler(struct PACKET_STRUCTURE *packet, unsigned char dispen
 	BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
 	unsigned char ConnectionState;
 	unsigned char *AlarmCode;
+	unsigned char GunTemp = 0;
+	unsigned char ChillerTemp = 0;
+	unsigned char noAlarm[6];
 
-	if(find && packet->Header.len <= 8)
+	memset(noAlarm, 0x00, 6);
+
+	if(find)
 	{
 	    ConnectionState = packet->Payload.data[0];
-	    AlarmCode = &packet->Payload.data[1];
+	    AlarmCode = packet->Header.len >= 8 ? &packet->Payload.data[1] : &noAlarm[0];
+	    GunTemp = packet->Header.len >= 10 ? packet->Payload.data[7] : GunTemp;
+	    ChillerTemp = packet->Header.len >= 10 ? packet->Payload.data[8] : ChillerTemp;
+
+	    chargingInfo[packet->Header.id - 1]->ConnectorTemp = GunTemp;
+	    chargingInfo[packet->Header.id - 1]->ChillerTemp = ChillerTemp;
 
 		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus != ConnectionState)
 		{
@@ -2034,8 +2015,11 @@ BOOL ConnectorStateHandler(struct PACKET_STRUCTURE *packet, unsigned char dispen
                     if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing ||
                         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Charging)
                     {
-                        PRINTF_FUNC("*********** Connector id %d Set Normal Stop Flag ***********\n", packet->Header.id);
-                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.NormalStopRequest = true;
+                        if(chargingInfo[packet->Header.id - 1]->SystemStatus != S_IDLE)
+                        {
+                            PRINTF_FUNC("*********** Connector id %d Set Normal Stop Flag ***********\n", packet->Header.id);
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.NormalStopRequest = true;
+                        }
                     }
                     break;
 
@@ -2375,26 +2359,37 @@ unsigned char DispenserWriteOtherVersionInfoHandler(struct PACKET_STRUCTURE *pac
 unsigned char DispenserWriteChargingInfoHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
     BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+    unsigned char gun = 0;
 
     if(find)
     {
+        gun = packet->Header.id - 1;
+        unsigned short diffVoltage = 0, diffCurrent = 0;
         unsigned short voltage = (packet->Payload.data[0] << 8) + (packet->Payload.data[1]);
         unsigned short current = (packet->Payload.data[2] << 8) + (packet->Payload.data[3]);
         //unsigned int time = (packet->Payload.data[4] << 24) + (packet->Payload.data[5] << 16) + (packet->Payload.data[6] << 8) + (packet->Payload.data[7]);
         unsigned char soc = (packet->Payload.data[8]);
 
-        if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingVoltage / 10) != (voltage / 10) ||
-            (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingCurrent / 10) != (current / 10) ||
-            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteSoc != soc)
+        diffVoltage = voltage >= ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingVoltage ?
+            voltage - ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingVoltage :
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingVoltage - voltage;
+
+        diffCurrent = current >= ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingCurrent ?
+            current - ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingCurrent :
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingCurrent - current;
+
+        if(diffVoltage > 10 || diffCurrent > 10 || ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteSoc != soc)
         {
-            PRINTF_FUNC("Connector %d Charging Info: Voltage %4dV Current %4dA Soc %d\% ", packet->Header.id, voltage, current, soc);
+            PRINTF_FUNC("Connector %d Charging Info: Voltage: %4d.%d V, Current: %3d.%d A, Soc: %3d, Temp: %3d, Chiller: %3d",
+                packet->Header.id, (voltage / 10), (voltage % 10), (current / 10), (current % 10), soc,
+                chargingInfo[gun]->ConnectorTemp - 60, chargingInfo[gun]->ChillerTemp - 60);
         }
 
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingVoltage = voltage;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingCurrent = current;
-        //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteRemainChargingDuration = time;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteSoc = soc;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterySoc = soc;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingVoltage = voltage;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteChargingCurrent = current;
+        //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteRemainChargingDuration = time;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].RemoteSoc = soc;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun].GeneralChargingData.EvBatterySoc = soc;
     }
     else
     {
@@ -3037,6 +3032,14 @@ int tcpSocketServerStart(void)
 	return 0;
 }
 
+void InitialConnector(void)
+{
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        chargingInfo[i] = &ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData;
+    }
+}
+
 int main(void)
 {
 	if(InitShareMemory() == FAIL)
@@ -3049,6 +3052,8 @@ int main(void)
 		return 0;
 	}
 
+	InitialConnector();
+
 	// wait for self test completed
     while(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
     {

+ 290 - 476
EVSE/Projects/DO360/Apps/Module_InternalComm.c

@@ -60,6 +60,13 @@ struct LedModuleData			*ShmLedModuleData;
 struct PsuData 					*ShmPsuData;
 struct OCPP16Data				*ShmOCPP16Data;
 ChargerInfoData                 *ShmChargerInfo;
+PsuGroupingInfoData             *ShmPsuGrouping;
+PsuGroupOutputRelay             *ShmOutputRelayConfig[MAX_GROUP_QUANTITY];
+PsuGroupOutputRelay             *ShmOutputRelayConfirmed[MAX_GROUP_QUANTITY];
+PsuGroupParallelRelay           *ShmParallelRelayConfig;
+PsuGroupParallelRelay           *ShmParallelRelayConfirmed;
+RBRelayControl                  *LocationRelayCtrl[MAX_GROUP_QUANTITY];
+RBRelayControl                  *LocationRelayResponse[MAX_GROUP_QUANTITY];
 
 #define VIN_MAX_VOLTAGE_IEC         285	// 大於該值 : OVP
 #define VIN_MAX_REV_VOLTAGE_IEC     275 // 小於賦歸 OVP
@@ -110,7 +117,7 @@ ChargerInfoData                 *ShmChargerInfo;
 byte gunCount;
 byte acgunCount;
 // 槍資訊
-struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY + GENERAL_GUN_QUANTITY];
+struct ChargingInfoData *_chargingData[CONNECTOR_QUANTITY];
 struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
 
 bool _isOutputNoneMatch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -745,6 +752,8 @@ void GetPersentOutputVol()
 
             _chargingData[0]->FuseChargingVoltage = ShmRelayModuleData[0]->Gun1FuseOutputVolt;
             _chargingData[0]->FireChargingVoltage = ShmRelayModuleData[0]->Gun1RelayOutputVolt;
+            _chargingData[3]->FuseChargingVoltage = ShmRelayModuleData[0]->Gun2FuseOutputVolt;
+            _chargingData[3]->FireChargingVoltage = ShmRelayModuleData[0]->Gun2RelayOutputVolt;
         }
 
         // DO360 RC2
@@ -757,6 +766,8 @@ void GetPersentOutputVol()
 
             _chargingData[1]->FuseChargingVoltage = ShmRelayModuleData[1]->Gun2FuseOutputVolt;
             _chargingData[1]->FireChargingVoltage = ShmRelayModuleData[1]->Gun2RelayOutputVolt;
+            _chargingData[2]->FuseChargingVoltage = ShmRelayModuleData[1]->Gun1FuseOutputVolt;
+            _chargingData[2]->FireChargingVoltage = ShmRelayModuleData[1]->Gun1RelayOutputVolt;
         }
     }
     else
@@ -799,15 +810,94 @@ void GetFanSpeed()
 // 讀取 Relay 狀態
 void GetRelayOutputStatus()
 {
-//	if (Query_Relay_Output(Uart5Fd, Addr.Relay, &regRelay) == PASS)
-//	{
-//		regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
-//	}
+    unsigned char location = 0;
+
+    if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC1, &regRelay[0]) == PASS)
+    {
+        regRelay[0].relay_event.bits.AC_Contactor = outputRelay[0].relay_event.bits.AC_Contactor;
+    }
+    if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
+    {
+        if(Query_Relay_Output(Uart5Fd, Addr.DO360_RC2, &regRelay[1]) == PASS)
+        {
+            regRelay[1].relay_event.bits.AC_Contactor = outputRelay[1].relay_event.bits.AC_Contactor;
+        }
+    }
+
+    // update output relay feedback status
+    for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
+    {
+        location = ShmPsuGrouping->GroupCollection[i].Location;
+
+        if(ShmOutputRelayConfirmed[i]->bits.Output_N != LocationRelayResponse[location]->bits.Gun_N)
+        {
+            PRINTF_FUNC("Gun %d Get K1K2 N %s at Location %d",
+                i + 1, LocationRelayResponse[location]->bits.Gun_N ? "On" : "Off", location + 1);
+        }
+        ShmOutputRelayConfirmed[i]->bits.Output_N = LocationRelayResponse[location]->bits.Gun_N;
+
+        if(ShmOutputRelayConfirmed[i]->bits.Output_P != LocationRelayResponse[location]->bits.Gun_P)
+        {
+            PRINTF_FUNC("Gun %d Get K1K2 P %s at Location %d",
+                i + 1, LocationRelayResponse[location]->bits.Gun_P ? "On" : "Off", location + 1);
+        }
+        ShmOutputRelayConfirmed[i]->bits.Output_P = LocationRelayResponse[location]->bits.Gun_P;
+    }
+
+    // update parallel relay feedback status
+    for(int i = 0; i < ShmChargerInfo->Control.MaxConnector - 1; i++)
+    {
+        bool relayOnOff = 0;
+
+        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
+        {
+            relayOnOff = LocationRelayResponse[i]->bits.Gun_Parallel_N_P;
+        }
+        else
+        {
+            bool original = ShmParallelRelayConfig->CtrlValue & (1 << i) ? false : true;
+
+            relayOnOff = LocationRelayResponse[i]->bits.Gun_Parallel_N_P == LocationRelayResponse[i + 1]->bits.Gun_Parallel_N_P ?
+                LocationRelayResponse[i]->bits.Gun_Parallel_N_P : original;
+#if 0
+            if(LocationRelayResponse[i]->bits.Gun_Parallel_N_P != LocationRelayResponse[i + 1]->bits.Gun_Parallel_N_P)
+            {
+                PRINTF_FUNC("Parallel Relay N & P at Location %d is Not Match: %d, %d",
+                    i + 1, LocationRelayResponse[i]->bits.Gun_Parallel_N_P, LocationRelayResponse[i + 1]->bits.Gun_Parallel_N_P);
+            }
+#endif
+        }
+
+        if((ShmParallelRelayConfirmed->CtrlValue & (1 << i)) != (relayOnOff << i))
+        {
+            PRINTF_FUNC("Get Parallel Relay N & P %s at Location %d", relayOnOff ? "On" : "Off", i + 1);
+        }
+
+        if(relayOnOff)
+        {
+            ShmParallelRelayConfirmed->CtrlValue |= 1 << i;
+        }
+        else
+        {
+            ShmParallelRelayConfirmed->CtrlValue &= ~(1 << i);
+        }
+    }
 }
 
 // 確認 K1 K2 relay 的狀態
 void CheckK1K2RelayOutput(byte index)
 {
+    unsigned char location = 0;
+    if(index < MAX_GROUP_QUANTITY && index < ShmChargerInfo->Control.MaxConnector)
+    {
+        location = ShmPsuGrouping->GroupCollection[index].Location;
+
+        if(LocationRelayCtrl[location]->bits.Gun_N == LocationRelayCtrl[location]->bits.Gun_P)
+        {
+            _chargingData[index]->RelayK1K2Status = LocationRelayCtrl[location]->bits.Gun_N ? YES : NO;
+        }
+    }
+#if 0
     if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
     {
         // two relay board
@@ -858,6 +948,7 @@ void CheckK1K2RelayOutput(byte index)
     }
 //	PRINTF_FUNC("Check Relay Output. index = %d, RelayKPK2Status = %d, BridgeRelayStatus = %d \n",
 //			index, _chargingData[index]->RelayKPK2Status, ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus);
+#endif
 }
 
 void GetGfdAdc()
@@ -1046,356 +1137,91 @@ void SetFanModuleSpeed()
 //==========================================
 void SetK1K2RelayStatus(byte index)
 {
-	if (_chargingData[index]->SystemStatus < S_PREPARING_FOR_EVSE)
-	{
-        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
+    unsigned char location = 0;
+
+    if(index < MAX_GROUP_QUANTITY && index < ShmChargerInfo->Control.MaxConnector)
+    {
+        if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                _chargingData[index]->SystemStatus <= S_CHARGING))
         {
-            // two relay board
-            if(index == 0)
-            {
-                if(regRelay[0].relay_event.bits.Gun1_P == YES)
-                    outputRelay[0].relay_event.bits.Gun1_P = NO;
-                if (regRelay[0].relay_event.bits.Gun1_N == YES)
-                    outputRelay[0].relay_event.bits.Gun1_N = NO;
-            }
-            if(index == 1)
+            if(!ShmOutputRelayConfig[index]->bits.Output_N || !ShmOutputRelayConfig[index]->bits.Output_P)
             {
-                if(regRelay[1].relay_event.bits.Gun2_P == YES)
-                    outputRelay[1].relay_event.bits.Gun2_P = NO;
-                if (regRelay[1].relay_event.bits.Gun2_N == YES)
-                    outputRelay[1].relay_event.bits.Gun2_N = NO;
+                PRINTF_FUNC("Gun %d Set K1K2 Close And Prepare To Charging", index + 1);
             }
+            ShmOutputRelayConfig[index]->bits.Output_N = true;
+            ShmOutputRelayConfig[index]->bits.Output_P = true;
         }
-        else
+        else if ((_chargingData[index]->SystemStatus >= S_TERMINATING &&
+                _chargingData[index]->SystemStatus <= S_COMPLETE) ||
+                _chargingData[index]->SystemStatus == S_ALARM)
         {
-            // only one relay board
-            if(index == 0)
-            {
-                if(regRelay[0].relay_event.bits.Gun1_P == YES)
-                    outputRelay[0].relay_event.bits.Gun1_P = NO;
-                if (regRelay[0].relay_event.bits.Gun1_N == YES)
-                    outputRelay[0].relay_event.bits.Gun1_N = NO;
-            }
-            if(index == 1)
-            {
-                if(regRelay[0].relay_event.bits.Gun2_P == YES)
-                    outputRelay[0].relay_event.bits.Gun2_P = NO;
-                if (regRelay[0].relay_event.bits.Gun2_N == YES)
-                    outputRelay[0].relay_event.bits.Gun2_N = NO;
-            }
-        }
-	}
-	else if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE &&
-			_chargingData[index]->SystemStatus <= S_CHARGING))
-	{
-		if (_chargingData[index]->RelayWeldingCheck == YES)
-		{
-            if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-            {
-                // two relay board
-                if(index == 0)
-                {
-                    if(regRelay[0].relay_event.bits.Gun1_N == NO)
-                        outputRelay[0].relay_event.bits.Gun1_N = YES;
-                    if (regRelay[0].relay_event.bits.Gun1_P == NO)
-                        outputRelay[0].relay_event.bits.Gun1_P = YES;
-                }
-                if(index == 1)
-                {
-                    if(regRelay[1].relay_event.bits.Gun2_N == NO)
-                        outputRelay[1].relay_event.bits.Gun2_N = YES;
-                    if (regRelay[1].relay_event.bits.Gun2_P == NO)
-                        outputRelay[1].relay_event.bits.Gun2_P = YES;
-                }
-            }
-            else
+            if ((_chargingData[index]->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR)
             {
-                // only one relay board
-                if(index == 0)
-                {
-                    if(regRelay[0].relay_event.bits.Gun1_N == NO)
-                        outputRelay[0].relay_event.bits.Gun1_N = YES;
-                    if (regRelay[0].relay_event.bits.Gun1_P == NO)
-                        outputRelay[0].relay_event.bits.Gun1_P = YES;
-                }
-                if(index == 1)
-                {
-                    if(regRelay[0].relay_event.bits.Gun2_N == NO)
-                        outputRelay[0].relay_event.bits.Gun2_N = YES;
-                    if (regRelay[0].relay_event.bits.Gun2_P == NO)
-                        outputRelay[0].relay_event.bits.Gun2_P = YES;
-                }
-            }
-		}
-	}
-	else if ((_chargingData[index]->SystemStatus >= S_TERMINATING &&
-			_chargingData[index]->SystemStatus <= S_COMPLETE) ||
-            _chargingData[index]->SystemStatus == S_ALARM)
-	{
-		if ((_chargingData[index]->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR)
-		{
-            if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-            {
-                // two relay board
-                if(index == 0)
-                {
-                    if(regRelay[0].relay_event.bits.Gun1_P == YES)
-                        outputRelay[0].relay_event.bits.Gun1_P = NO;
-                    if (regRelay[0].relay_event.bits.Gun1_N == YES)
-                        outputRelay[0].relay_event.bits.Gun1_N = NO;
-                }
-                if(index == 1)
+                if(ShmOutputRelayConfig[index]->bits.Output_N || ShmOutputRelayConfig[index]->bits.Output_P)
                 {
-                    if(regRelay[1].relay_event.bits.Gun2_P == YES)
-                        outputRelay[1].relay_event.bits.Gun2_P = NO;
-                    if (regRelay[1].relay_event.bits.Gun2_N == YES)
-                        outputRelay[1].relay_event.bits.Gun2_N = NO;
+                    PRINTF_FUNC("Gun %d Set K1K2 Open And Charging Stop", index + 1);
                 }
+                ShmOutputRelayConfig[index]->bits.Output_N = false;
+                ShmOutputRelayConfig[index]->bits.Output_P = false;
             }
-            else
+        }
+        else
+        {
+            if(ShmOutputRelayConfig[index]->bits.Output_N || ShmOutputRelayConfig[index]->bits.Output_P)
             {
-                // only one relay board
-                if(index == 0)
-                {
-                    if(regRelay[0].relay_event.bits.Gun1_P == YES)
-                        outputRelay[0].relay_event.bits.Gun1_P = NO;
-                    if (regRelay[0].relay_event.bits.Gun1_N == YES)
-                        outputRelay[0].relay_event.bits.Gun1_N = NO;
-                }
-                if(index == 1)
-                {
-                    if(regRelay[0].relay_event.bits.Gun2_P == YES)
-                        outputRelay[0].relay_event.bits.Gun2_P = NO;
-                    if (regRelay[0].relay_event.bits.Gun2_N == YES)
-                        outputRelay[0].relay_event.bits.Gun2_N = NO;
-                }
+                PRINTF_FUNC("Gun %d Set K1K2 Open At Idle Mode", index + 1);
             }
-		}
-	}
-	else if (_chargingData[index]->SystemStatus == S_CCS_PRECHARGE_ST0)
-	{
+            ShmOutputRelayConfig[index]->bits.Output_N = false;
+            ShmOutputRelayConfig[index]->bits.Output_P = false;
+        }
 
-	}
-	else if (_chargingData[index]->SystemStatus == S_CCS_PRECHARGE_ST1)
-	{
+        location = ShmPsuGrouping->GroupCollection[index].Location;
 
-	}
+        if(ShmOutputRelayConfig[index]->bits.Output_N != LocationRelayCtrl[location]->bits.Gun_N)
+        {
+#if 0
+            PRINTF_FUNC("Connector %d Set K1K2 N %s at Location %d",
+                index + 1, ShmOutputRelayConfig[index]->bits.Output_N ? "On" : "Off", location + 1);
+#endif
+        }
+        LocationRelayCtrl[location]->bits.Gun_N = ShmOutputRelayConfig[index]->bits.Output_N;
+
+        if(ShmOutputRelayConfig[index]->bits.Output_P != LocationRelayCtrl[location]->bits.Gun_P)
+        {
+#if 0
+            PRINTF_FUNC("Connector %d Set K1K2 P %s at Location %d",
+                index + 1, ShmOutputRelayConfig[index]->bits.Output_P ? "On" : "Off", location + 1);
+#endif
+        }
+        LocationRelayCtrl[location]->bits.Gun_P = ShmOutputRelayConfig[index]->bits.Output_P;
+    }
 }
 
 void SetParalleRelayStatus()
 {
-	// 之後雙槍單模機種,橋接都會上
-	if (gunCount >= 2)
-	{
-		if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING ||
-				((_chargingData[0]->SystemStatus == S_IDLE || _chargingData[0]->SystemStatus == S_MAINTAIN || _chargingData[0]->SystemStatus == S_FAULT) &&
-				(_chargingData[1]->SystemStatus == S_IDLE || _chargingData[1]->SystemStatus == S_MAINTAIN || _chargingData[1]->SystemStatus == S_FAULT)))
-		{
-            if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-            {
-                // two relay board
-                // 初始化~ 不搭橋接
+    for(int i = 0; i < ShmChargerInfo->Control.MaxConnector - 1; i++)
+    {
+        if((ShmParallelRelayConfig->CtrlValue & (1 << i)) != (LocationRelayCtrl[i]->bits.Gun_Parallel_N_P << i))
+        {
 #if 0
-                if (regRelay[0].relay_event.bits.Gun1_Parallel_P == YES)
-                    outputRelay[0].relay_event.bits.Gun1_Parallel_P = NO;
-                if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                    outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                    outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                    outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                if (regRelay[1].relay_event.bits.Gun1_Parallel_P == YES)
-                    outputRelay[1].relay_event.bits.Gun1_Parallel_P = NO;
-                if (regRelay[1].relay_event.bits.Gun1_Parallel_N == YES)
-                    outputRelay[1].relay_event.bits.Gun1_Parallel_N = NO;
+            PRINTF_FUNC("Set Parallel Relay N & P %s at Location %d",
+                (ShmParallelRelayConfig->CtrlValue & (1 << i)) ? "On" : "Off", i + 1);
 #endif
-                // gun 1 & gun 3 parallel relay enable
-                if (regRelay[0].relay_event.bits.Gun1_Parallel_P == NO)
-                    outputRelay[0].relay_event.bits.Gun1_Parallel_P = YES;
-                if (regRelay[0].relay_event.bits.Gun1_Parallel_N == NO)
-                    outputRelay[0].relay_event.bits.Gun1_Parallel_N = YES;
-
-                // gun 3 & gun 4 parallel relay disable
-                if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                    outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                    outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-
-                // gun 4 & gun 2 parallel relay enable
-                if (regRelay[1].relay_event.bits.Gun1_Parallel_P == NO)
-                    outputRelay[1].relay_event.bits.Gun1_Parallel_P = YES;
-                if (regRelay[1].relay_event.bits.Gun1_Parallel_N == NO)
-                    outputRelay[1].relay_event.bits.Gun1_Parallel_N = YES;
-            }
-            else
+        }
+        LocationRelayCtrl[i]->bits.Gun_Parallel_N_P = (ShmParallelRelayConfig->CtrlValue & (1 << i)) ? YES : NO;
+
+        if(!ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
+        {
+            if((ShmParallelRelayConfig->CtrlValue & (1 << i)) != (LocationRelayCtrl[i]->bits.Gun_Parallel_P << i))
             {
-                // only one relay board
-                // 初始化~ 不搭橋接
-                if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                    outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                    outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-            }
-		}
-		else
-		{
-			if (_chargingData[0]->IsReadyToCharging == YES ||
-					_chargingData[1]->IsReadyToCharging == YES)
-			{
-				// ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************
-				if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
-				{
-					if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_M_TO_A)
-					{
-                        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-                        {
-                            // two relay board
-                            // 最大充 - 搭上橋接
-#if 0
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_P = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = YES;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_P == NO)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_P = YES;
-#endif
-                            // gun 3 & gun 4 parallel relay enable
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = YES;
-                        }
-                        else
-                        {
-                            // only one relay board
-                            // 最大充 - 搭上橋接
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                        }
-					}
-					else
-					{
-                        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-                        {
-                            // two relay board
-                            // 平均充 - 不搭
-#if 0
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_P == YES)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_P = NO;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_N = NO;
-#endif
-                            // gun 3 & gun 4 parallel relay disable
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                        }
-                        else
-                        {
-                            // only one relay board
-                            // 平均充 - 不搭
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                        }
-					}
-				}
-				else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
-				{
-					if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_A_TO_M)
-					{
-                        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-                        {
-                            // two relay board
-                            // 平均充 - 不搭
-#if 0
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_P == YES)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_P = NO;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_N = NO;
-#endif
-                            // gun 3 & gun 4 parallel relay disable
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                        }
-                        else
-                        {
-                            // only one relay board
-                            // 平均充 - 不搭
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = NO;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == YES)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = NO;
-                        }
-					}
-					else
-					{
-                        if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
-                        {
-                            // two relay board
-                            // 最大充 - 搭上橋接
 #if 0
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_P = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = YES;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[1].relay_event.bits.Gun1_Parallel_P == NO)
-                                outputRelay[1].relay_event.bits.Gun1_Parallel_P = YES;
+                PRINTF_FUNC("Set Parallel Relay P %s at Location %d",
+                    (ShmParallelRelayConfig->CtrlValue & (1 << i)) ? "On" : "Off", i + 1);
 #endif
-                            // gun 3 & gun 4 parallel relay enable
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_P == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_P = YES;
-                        }
-                        else
-                        {
-                            // only one relay board
-                            // 最大充 - 搭上橋接
-                            if (regRelay[0].relay_event.bits.Gun1_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun1_Parallel_N = YES;
-                            if (regRelay[0].relay_event.bits.Gun2_Parallel_N == NO)
-                                outputRelay[0].relay_event.bits.Gun2_Parallel_N = YES;
-                        }
-					}
-				}
-			}
-		}
-	}
+            }
+            LocationRelayCtrl[i + 1]->bits.Gun_Parallel_N_P = (ShmParallelRelayConfig->CtrlValue & (1 << i)) ? YES : NO;
+        }
+    }
 }
 
 void SetAcContactorStatus(void)
@@ -1745,6 +1571,33 @@ int InitShareMemory()
         #endif
         result = FAIL;
     }
+    if(result == PASS)
+    {
+        ShmPsuGrouping = &ShmChargerInfo->PsuGrouping;
+        for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
+        {
+            ShmOutputRelayConfig[i] = &ShmChargerInfo->PsuGrouping.OutputRelayConfig[i];
+            ShmOutputRelayConfirmed[i] = &ShmChargerInfo->PsuGrouping.OutputRelayConfirmed[i];
+        }
+        ShmParallelRelayConfig = &ShmChargerInfo->PsuGrouping.ParallelRelayConfig;
+        ShmParallelRelayConfirmed = &ShmChargerInfo->PsuGrouping.ParallelRelayConfirmed;
+
+        if(ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable == false)
+        {
+            LocationRelayCtrl[0] = (RBRelayControl *)&outputRelay[0].relay_event.relay_status[1];
+            LocationRelayCtrl[1] = (RBRelayControl *)&outputRelay[0].relay_event.relay_status[2];
+            LocationRelayResponse[0] = (RBRelayControl *)&regRelay[0].relay_event.relay_status[1];
+            LocationRelayResponse[1] = (RBRelayControl *)&regRelay[0].relay_event.relay_status[2];
+
+            if(ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable)
+            {
+                LocationRelayCtrl[2] = (RBRelayControl *)&outputRelay[1].relay_event.relay_status[1];
+                LocationRelayCtrl[3] = (RBRelayControl *)&outputRelay[1].relay_event.relay_status[2];
+                LocationRelayResponse[2] = (RBRelayControl *)&regRelay[1].relay_event.relay_status[1];
+                LocationRelayResponse[3] = (RBRelayControl *)&regRelay[1].relay_event.relay_status[2];
+            }
+        }
+    }
 
 	return result;
 }
@@ -1885,109 +1738,84 @@ void Initialization()
 
 bool IsNoneMatchRelayStatus(byte index)
 {
-	bool result = false;
+    bool result = false;
 
-	if ((regRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor) ||
-		(regRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge) ||
-		(regRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P) ||
-		(regRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N) ||
-		(regRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P) ||
-		(regRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N) ||
-		(regRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P) ||
-		(regRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N) ||
-		(regRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P) ||
-		(regRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N))
-	{
-		if (regRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor)
-		{
-		    if(TempRegRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor)
-		    {
-		        PRINTF_FUNC("[%d]AC Contact Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.AC_Contactor == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.AC_Contactor = outputRelay[index].relay_event.bits.AC_Contactor;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge)
-		{
-		    if(TempRegRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge)
-		    {
-		        PRINTF_FUNC("[%d]CCS Precharge Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.CCS_Precharge == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.CCS_Precharge = outputRelay[index].relay_event.bits.CCS_Precharge;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P)
-		    {
-		        PRINTF_FUNC("[%d]SMR1:D+ Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun1_P == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun1_P = outputRelay[index].relay_event.bits.Gun1_P;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N)
-		    {
-		        PRINTF_FUNC("[%d]SMR1:D- Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun1_N == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun1_N = outputRelay[index].relay_event.bits.Gun1_N;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P)
-		    {
-		        PRINTF_FUNC("[%d]SMR2:D+ Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun2_P == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun2_P = outputRelay[index].relay_event.bits.Gun2_P;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N)
-		    {
-		        PRINTF_FUNC("[%d]SMR2:D- Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun2_N == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun2_N = outputRelay[index].relay_event.bits.Gun2_N;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P)
-		    {
-		        PRINTF_FUNC("[%d]Parallel:D+ Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun1_Parallel_P == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun1_Parallel_P = outputRelay[index].relay_event.bits.Gun1_Parallel_P;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N)
-		    {
-		        PRINTF_FUNC("[%d]Parallel:D- Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun1_Parallel_N == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun1_Parallel_N = outputRelay[index].relay_event.bits.Gun1_Parallel_N;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P)
-		    {
-		        PRINTF_FUNC("[%d]Parallel2:D+ Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun2_Parallel_P == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun2_Parallel_P = outputRelay[index].relay_event.bits.Gun2_Parallel_P;
-		    }
-		}
-		if (regRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N)
-		{
-		    if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N)
-		    {
-		        PRINTF_FUNC("[%d]Parallel2:D- Relay none match, need to %s", index,
-                    outputRelay[index].relay_event.bits.Gun2_Parallel_N == YES ? "On" : "Off");
-		        TempRegRelay[index].relay_event.bits.Gun2_Parallel_N = outputRelay[index].relay_event.bits.Gun2_Parallel_N;
-		    }
-		}
+    if(regRelay[index].relay_event.relay_status[0] != outputRelay[index].relay_event.relay_status[0] ||
+        regRelay[index].relay_event.relay_status[1] != outputRelay[index].relay_event.relay_status[1] ||
+        regRelay[index].relay_event.relay_status[2] != outputRelay[index].relay_event.relay_status[2])
+	{
+        if(TempRegRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor)
+        {
+            PRINTF_FUNC("[%d]AC Contact Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.AC_Contactor == YES ? "On" : "Off");
+        }
+        if(TempRegRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge)
+        {
+#if 0
+            PRINTF_FUNC("[%d]CCS Precharge Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.CCS_Precharge == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P)
+        {
+#if 0
+            PRINTF_FUNC("[%d]SMR1:D+ Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun1_P == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N)
+        {
+#if 0
+            PRINTF_FUNC("[%d]SMR1:D- Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun1_N == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P)
+        {
+#if 0
+            PRINTF_FUNC("[%d]SMR2:D+ Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun2_P == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N)
+        {
+#if 0
+            PRINTF_FUNC("[%d]SMR2:D- Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun2_N == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P)
+        {
+#if 0
+            PRINTF_FUNC("[%d]Parallel:D+ Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun1_Parallel_P == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N)
+        {
+#if 0
+            PRINTF_FUNC("[%d]Parallel:D- Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun1_Parallel_N == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P)
+        {
+#if 0
+            PRINTF_FUNC("[%d]Parallel2:D+ Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun2_Parallel_P == YES ? "On" : "Off");
+#endif
+        }
+        if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N)
+        {
+#if 0
+            PRINTF_FUNC("[%d]Parallel2:D- Relay none match, need to %s", index,
+                outputRelay[index].relay_event.bits.Gun2_Parallel_N == YES ? "On" : "Off");
+#endif
+        }
+
+        TempRegRelay[index].relay_event.relay_status[0] = outputRelay[index].relay_event.relay_status[0];
+        TempRegRelay[index].relay_event.relay_status[1] = outputRelay[index].relay_event.relay_status[1];
+        TempRegRelay[index].relay_event.relay_status[2] = outputRelay[index].relay_event.relay_status[2];
 
 		result = true;
 	}
@@ -1995,20 +1823,6 @@ bool IsNoneMatchRelayStatus(byte index)
 	return result;
 }
 
-void MatchRelayStatus()
-{
-	// 因為 AC Contactor 沒有 Feedback,所以暫時先這樣處理
-	//regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor;
-//	ShmSysConfigAndInfo->SysInfo.AcContactorStatus  = regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor;
-//	regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
-//	regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
-//	regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
-//	regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
-//	regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
-//	regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
-//	regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
-}
-
 void CheckRelayStatusByADC()
 {
 	if (ShmRelayModuleData[0]->Gun1FuseOutputVolt > 0 && ShmRelayModuleData[0]->Gun1RelayOutputVolt > 0 &&
@@ -2624,7 +2438,7 @@ int main(void)
 		return 0;
 	}
 
-	gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
+	gunCount = ShmChargerInfo->Control.MaxConnector;
 	acgunCount = ShmSysConfigAndInfo->SysConfig.AcConnectorCount;
 	// Open Uart5 for RB
 	Uart5Fd = InitComPort();
@@ -2668,7 +2482,7 @@ int main(void)
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
             if(ShmChargerInfo->Control.SysCtrl.bits.RelayBoardDisable == false)
             {
-                if (ShmRelayModuleData[0]->SelfTest_Comp == NO)
+                if (ShmRelayModuleData[0]->SelfTest_Comp == NO && !ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
                 {
                     // clena fw version
                     memset(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, 0x00, 32);
@@ -2690,7 +2504,7 @@ int main(void)
 
                 // DO360 RC2
                 if (ShmChargerInfo->Control.SysCtrl.bits.SecondRelayBoardEnable == true &&
-                        ShmRelayModuleData[1]->SelfTest_Comp == NO)
+                    ShmRelayModuleData[1]->SelfTest_Comp == NO && !ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
                 {
                     // clena fw version
                     memset(ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev, 0x00, 32);
@@ -2713,7 +2527,7 @@ int main(void)
 
             if(ShmChargerInfo->Control.SysCtrl.bits.FanBoardDisable == false)
             {
-                if (ShmFanModuleData->SelfTest_Comp == NO)
+                if (ShmFanModuleData->SelfTest_Comp == NO && !ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
                 {
                     // clena fw version
                     memset(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, 0x00, 32);
@@ -2731,7 +2545,8 @@ int main(void)
                 }
             }
 
-            if(_RelaySelfTestOK == YES)
+
+            if(_RelaySelfTestOK == YES || ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
             {
                 // ==============優先權最高 10 ms ==============
                 // 輸出電壓
@@ -2740,9 +2555,9 @@ int main(void)
                 // 三相輸入電壓
                 GetPresentInputVol();
 
-                //GetRelayOutputStatus();
+                GetRelayOutputStatus();
 
-                for (int i = 0; i < gunCount; i++)
+                for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
                 {
                     // check k1 k2 relay 狀態
                     CheckK1K2RelayOutput(i);
@@ -2797,16 +2612,15 @@ int main(void)
                 {
                     if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]))
                     {
-                        regRelay[0].relay_event.bits.AC_Contactor = outputRelay[0].relay_event.bits.AC_Contactor;
-                        regRelay[0].relay_event.bits.CCS_Precharge = outputRelay[0].relay_event.bits.CCS_Precharge;
-                        regRelay[0].relay_event.bits.Gun1_P = outputRelay[0].relay_event.bits.Gun1_P;
-                        regRelay[0].relay_event.bits.Gun1_N = outputRelay[0].relay_event.bits.Gun1_N;
-                        regRelay[0].relay_event.bits.Gun2_P = outputRelay[0].relay_event.bits.Gun2_P;
-                        regRelay[0].relay_event.bits.Gun2_N = outputRelay[0].relay_event.bits.Gun2_N;
-                        regRelay[0].relay_event.bits.Gun1_Parallel_P = outputRelay[0].relay_event.bits.Gun1_Parallel_P;
-                        regRelay[0].relay_event.bits.Gun1_Parallel_N = outputRelay[0].relay_event.bits.Gun1_Parallel_N;
-                        regRelay[0].relay_event.bits.Gun2_Parallel_P = outputRelay[0].relay_event.bits.Gun2_Parallel_P;
-                        regRelay[0].relay_event.bits.Gun2_Parallel_N = outputRelay[0].relay_event.bits.Gun2_Parallel_N;
+                        //regRelay[0].relay_event.relay_status[0] = outputRelay[0].relay_event.relay_status[0];
+                        //regRelay[0].relay_event.relay_status[1] = outputRelay[0].relay_event.relay_status[1];
+                        //regRelay[0].relay_event.relay_status[2] = outputRelay[0].relay_event.relay_status[2];
+                    }
+                    if(ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
+                    {
+                        regRelay[0].relay_event.relay_status[0] = outputRelay[0].relay_event.relay_status[0];
+                        regRelay[0].relay_event.relay_status[1] = outputRelay[0].relay_event.relay_status[1];
+                        regRelay[0].relay_event.relay_status[2] = outputRelay[0].relay_event.relay_status[2];
                     }
                 }
 
@@ -2817,21 +2631,21 @@ int main(void)
                     {
                         if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]))
                         {
-                            regRelay[1].relay_event.bits.AC_Contactor = outputRelay[1].relay_event.bits.AC_Contactor;
-                            regRelay[1].relay_event.bits.CCS_Precharge = outputRelay[1].relay_event.bits.CCS_Precharge;
-                            regRelay[1].relay_event.bits.Gun1_P = outputRelay[1].relay_event.bits.Gun1_P;
-                            regRelay[1].relay_event.bits.Gun1_N = outputRelay[1].relay_event.bits.Gun1_N;
-                            regRelay[1].relay_event.bits.Gun2_P = outputRelay[1].relay_event.bits.Gun2_P;
-                            regRelay[1].relay_event.bits.Gun2_N = outputRelay[1].relay_event.bits.Gun2_N;
-                            regRelay[1].relay_event.bits.Gun1_Parallel_P = outputRelay[1].relay_event.bits.Gun1_Parallel_P;
-                            regRelay[1].relay_event.bits.Gun1_Parallel_N = outputRelay[1].relay_event.bits.Gun1_Parallel_N;
-                            regRelay[1].relay_event.bits.Gun2_Parallel_P = outputRelay[1].relay_event.bits.Gun2_Parallel_P;
-                            regRelay[1].relay_event.bits.Gun2_Parallel_N = outputRelay[1].relay_event.bits.Gun2_Parallel_N;
+                            //regRelay[1].relay_event.relay_status[0] = outputRelay[1].relay_event.relay_status[0];
+                            //regRelay[1].relay_event.relay_status[1] = outputRelay[1].relay_event.relay_status[1];
+                            //regRelay[1].relay_event.relay_status[2] = outputRelay[1].relay_event.relay_status[2];
                         }
                     }
+                    if(ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
+                    {
+                        regRelay[1].relay_event.relay_status[0] = outputRelay[1].relay_event.relay_status[0];
+                        regRelay[1].relay_event.relay_status[1] = outputRelay[1].relay_event.relay_status[1];
+                        regRelay[1].relay_event.relay_status[2] = outputRelay[1].relay_event.relay_status[2];
+                    }
                 }
             }
 
+
             if (ShmFanModuleData->SelfTest_Comp == YES ||
                     strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 ||
                     ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0')

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


+ 12 - 4
EVSE/Projects/DO360/Apps/Module_PsuComm.h

@@ -33,12 +33,11 @@
 #include 	<stdbool.h>
 
 typedef unsigned char 		byte;
-typedef unsigned short 	word;
+typedef unsigned short 	    word;
 typedef unsigned int 		unit;
 
-unsigned char _gunCount;
-struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY + GENERAL_GUN_QUANTITY];
-bool isStartOutputSwitch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY + GENERAL_GUN_QUANTITY];
+struct ChargingInfoData *chargingInfo[CONNECTOR_QUANTITY];
+bool isStartOutputSwitch[CONNECTOR_QUANTITY];
 
 struct timeval _cmdSubPriority_time;
 struct timeval _derating_time;
@@ -71,3 +70,12 @@ enum _PSU_CMD_SEQ
 	_PSU_CMD_IVAILIABLE	= 12,
 	_PSU_CMD_TEMP		= 13
 };
+
+enum _CURRENT_CONFIG_MODE
+{
+    _CURRENT_MODE_NONE      = 0,
+    _CURRENT_MODE_BALANCE   = 1,
+    _CURRENT_MODE_INCREASE  = 2,
+    _CURRENT_MODE_DECREASE  = 3,
+    _CURRENT_MODE_DERATING  = 4,
+};

+ 778 - 28
EVSE/Projects/DO360/Apps/ReadCmdline.c

@@ -75,7 +75,10 @@ char *msg = "state : get gun state (index) \n"
 		"lock : get gun locked state (index) \n"
 		"self : self test state (x) \n"
 		"ver : ver of board (407 or index or rb or fan) \n"
-		"ac : get ac relay state (x) \n";
+		"ac : get ac relay state (x) \n"
+        "gunchg: set gun start charging \n"
+        "gunstp: set gun stop charging \n"
+        "gunext: extend gun capability \n";
 
 bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
 {
@@ -289,8 +292,6 @@ void RunStatusProc(char *v1, char *v2)
             printf("ConnectorAlarmCode = %s \n", _chargingData[_index]->ConnectorAlarmCode);
             printf("EvConnAlarmCode = %s \n", _chargingData[_index]->EvConnAlarmCode);
             printf("RemotenAlarmCode = %s \n", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[_index].RemotenAlarmCode);
-			//printf("ConnectorAlarmCode = %s \n", ShmOCPP16Data->StatusNotification[index].ErrorCode);
-			//printf("ConnectorAlarmCode = %s \n", ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
 		}
 		else
 		{
@@ -646,15 +647,48 @@ void SetGFDMode(char *v1)
 	ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag = mode;
 }
 
-void GetPsuTemp()
+// Gun  Temp  Chiller  PSU 0  PSU 1  PSU 2  ...
+//  1    XXX    XXX     XXX    XXX    XXX    XXX
+void GetTemperature(char *v1)
 {
-	for (byte index = 0; index < ShmPsuData->GroupCount; index++)
-	{
-		for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
-		{
-			printf("PSU Temp = %d \n", ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp);
-		}
-	}
+    bool show = false;
+    char strGunTemp[16], strChillerTemp[16];
+
+    if(strcmp(v1, "c") == 0)
+    {
+        printf("\r\n Get c Parameter");
+        show = true;
+    }
+    do
+    {
+        printf("\r\n Gun  Temp  Chiller  PSU 0  PSU 1  PSU 2  ...");
+        for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+        {
+            sprintf(strGunTemp, "N/A");
+            sprintf(strChillerTemp, "N/A");
+
+            if(_chargingData[i]->ConnectorTemp != 0 && _chargingData[i]->ConnectorTemp != 0xFF)
+            {
+                sprintf(strGunTemp, "%3d", _chargingData[i]->ConnectorTemp - 60);
+            }
+            if(_chargingData[i]->ChillerTemp != 0 && _chargingData[i]->ChillerTemp != 0xFF)
+            {
+                sprintf(strChillerTemp, "%3d", _chargingData[i]->ChillerTemp - 60);
+            }
+            printf("\r\n  %d    %s    %s  ", i + 1, strGunTemp, strChillerTemp);
+
+            for(int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
+            {
+                printf("   %3d ", ShmPsuData->PsuGroup[i].PsuModule[j].ExletTemp);
+            }
+        }
+        printf("\r\n");
+
+        if(show)
+        {
+            sleep(1);
+        }
+    }while(show);
 }
 
 void GetAcInputVol()
@@ -1520,36 +1554,37 @@ void RemoveGroupCollection(byte group, byte target)
     }
 }
 
-// Gun  Role  Quantity  Master   Member    OutputVoltage  OutputCurrent  AvailablePower  AvailableCurrent  StableCurrent  OutputRelay  ParallelRelay
-//  1    00       3       00    00 00 00       0000 V         0000 A         000 kW           0000 A          0000 A           00            XX
+// Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay
+//  1   (00)   00  3     00    [00] [00] [00]    0000 V     0000 A    0000 kW    0000 A   0000 A   00      XX
 void ShowGroupingInfo(void)
 {
     byte target = 0;
 
-    printf("\r\n Gun  Role  Quantity  Master   Member    OutputVoltage  OutputCurrent  AvailablePower  AvailableCurrent  StableCurrent  OutputRelay  ParallelRelay");
+    printf("\r\n Gun(Status)(Ro)(Q)  Master      Member      OutputVol  OutputCur  AvaiPower  AvaiCur  StabCur  K1K2  ParaRelay");
 
     for(int i = 0; i < 4; i++)
     {
         target = ShmPsuGrouping->Layout[i];
-        printf("\r\n  %d    %2d       %d       %02X    ",
-            target + 1, ShmGroupCollection[target].Role, ShmGroupCollection[target].Partner.Quantity, ShmGroupCollection[target].TargetGroup);
+        printf("\r\n  %d   (%2d)   %2d  %d     %02X    ",
+            target + 1, _chargingData[target]->SystemStatus, ShmGroupCollection[target].Role,
+            ShmGroupCollection[target].Partner.Quantity, ShmGroupCollection[target].TargetGroup);
 
         for(int j = 0; j < 3; j++)
         {
             if(ShmGroupCollection[target].Role == 1 && j < ShmGroupCollection[target].Partner.Quantity)
             {
-                printf("%02X ", ShmGroupCollection[target].Partner.Member[j]);
+                printf("[%02X] ", ShmGroupCollection[target].Partner.Member[j]);
             }
             else
             {
-                printf("   ");
+                printf("     ");
             }
         }
-        printf("      %4d V         %4d A         %3d kW           %4d A          %4d A    ",
+        printf("   %4d V     %4d A    %4d kW    %4d A   %4d A   ",
             (int)_chargingData[target]->PresentChargingVoltage, (int)_chargingData[target]->PresentChargingCurrent,
             (int)(_chargingData[target]->AvailableChargingPower / 10), (int)(_chargingData[target]->AvailableChargingCurrent / 10),
             (int)(_chargingData[target]->DeratingChargingCurrent / 10));
-        printf("       %02X            %02X",ShmPsuGrouping->OutputRelayConfig[target].CtrlValue, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
+        printf("%02X      %02X",ShmPsuGrouping->OutputRelayConfig[target].CtrlValue, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
     }
     printf("\r\n\r\nSystem Capability Current = %4d.%01d A, Power = %3d.%01d kW",
         (ShmPsuData->SystemAvailableCurrent / 10), (ShmPsuData->SystemAvailableCurrent % 10),
@@ -1832,6 +1867,10 @@ void SimplePsuGroupStartCharging(byte group)
     {
         AddGroupCollection(partner.Member[i], group);
     }
+
+    ShmPsuGrouping->OutputRelayConfig[group].bits.Output_N = true;
+    ShmPsuGrouping->OutputRelayConfig[group].bits.Output_P = true;
+
 #if 0
     // search from left
     location = ShmGroupCollection[group].Location - 1;
@@ -1901,6 +1940,9 @@ void PsuGroupStopCharging(byte group)
         }
     }
     SetGroupToIdle(group);
+
+    ShmPsuGrouping->OutputRelayConfig[group].bits.Output_N = false;
+    ShmPsuGrouping->OutputRelayConfig[group].bits.Output_P = false;
 }
 
 void RunSimplePsuGrouping(char *v1, char *v2)
@@ -1944,8 +1986,8 @@ void ShowCabinetInfo(void)
 {
     int ipAddress = 0;
 
-    printf("\r\nPower Cabinet Charging Mode = %d, ReAssignedFlag = %d",
-        ShmSysConfigAndInfo->SysInfo.MainChargingMode, ShmSysConfigAndInfo->SysInfo.ReAssignedFlag);
+    printf("\r\nPower Cabinet Charging Mode = %d, ReAssignedFlag = %d, Psu Work Step = %d",
+        ShmSysConfigAndInfo->SysInfo.MainChargingMode, ShmSysConfigAndInfo->SysInfo.ReAssignedFlag, ShmPsuData->Work_Step);
 
     printf("\r\n Dispenser: %d / %d, Connector: %d / %d",
         ShmSysConfigAndInfo->SysInfo.DispenserInfo.PresentDispenserQuantity,
@@ -1953,6 +1995,12 @@ void ShowCabinetInfo(void)
         ShmSysConfigAndInfo->SysInfo.DispenserInfo.PresentConnectorQuantity,
         ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity);
 
+    for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
+    {
+        printf("\r\n Connector[%d] Index: %d, Status = %2d , %s", i, _chargingData[i]->Index, _chargingData[i]->SystemStatus,
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Enable ? "Enable" : "Disable");
+    }
+
     for(int i = 0; i < ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity; i++)
     {
         printf("\r\n  Dispenser[%d] Status: %d", i, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].LocalStatus);
@@ -1986,10 +2034,10 @@ void ShowCabinetInfo(void)
 void SetTestControl(char *v1, char *v2)
 {
     int testItem = 0;
-    int testItemLen = 2;
+    int testItemLen = 3;
     int enable = 0;
-    char strTest[32][32] = {"tbl", "tfsb"};
-    char strItem[32][32] = {"Balance", "Fast Standby Time"};
+    char strTest[32][32] = {"tbl", "tfsb", "chgsm"};
+    char strItem[32][32] = {"Balance", "Fast Standby Time", "Charging Simulation"};
 
     enable = atoi(v2);
 
@@ -2032,6 +2080,642 @@ void SetTestControl(char *v1, char *v2)
     printf("\r\n");
 }
 
+// Gun  Role  Master  K1K2  GTVoltage  GTCurrent  StableCurrent  OutputLoading  GunLoading
+//  1    00     00      0     0000 V    000.0 A       0000 A         XXX.XX       XXX.XX
+void ShowGroupingDemand(void)
+{
+    byte target = 0;
+    unsigned char k1k2 = 0;
+
+    printf("\r\n Gun  Role  Master  K1K2  GTVoltage  GTCurrent  StableCurrent  OutputLoading  GunLoading");
+
+    for(int i = 0; i < 4; i++)
+    {
+        target = ShmPsuGrouping->Layout[i];
+        if(ShmGroupCollection[target].TargetGroup != 0)
+        {
+            k1k2 = _chargingData[ShmGroupCollection[target].TargetGroup - 1]->RelayK1K2Status;
+        }
+        else
+        {
+            k1k2 = _chargingData[target]->RelayK1K2Status;
+        }
+
+        printf("\r\n  %d    %2d     %02X      %d     %4d V    %3d.%d A       %4d A         %3d.%02d",
+            target + 1, ShmGroupCollection[target].Role, ShmGroupCollection[target].TargetGroup, k1k2,
+            (ShmPsuGrouping->GroupOutput[target].GTargetVoltage / 10),
+            (ShmPsuGrouping->GroupOutput[target].GTargetCurrent / 10),
+            (ShmPsuGrouping->GroupOutput[target].GTargetCurrent % 10),
+            (int)(_chargingData[target]->AvailableChargingCurrent / 10),
+            (ShmPsuGrouping->GroupOutput[target].OutputLoading / 100),
+            (ShmPsuGrouping->GroupOutput[target].OutputLoading % 100));
+        if(ShmGroupCollection[target].TargetGroup == target + 1)
+        {
+            printf("       %3d.%02d", (ShmGroupCollection[target].GunLoading / 100), (ShmGroupCollection[target].GunLoading % 100));
+        }
+    }
+
+    printf("\r\n\r\n");
+}
+
+// v1: gun
+// v2: voltage
+// v3: current
+void SetGunStartCharging(char *v1, char *v2, char *v3)
+{
+    int gun = 0;
+    float _voltage = 0, _current = 0;
+
+    gun = atoi(v1);
+    _voltage = atof(v2);
+    _current = atof(v3);
+
+    if(gun <= 0 || gun > GENERAL_GUN_QUANTITY || _voltage < 0 || _voltage > 1000 || _current < 0 || _current > 1200)
+    {
+        printf("\r\nGun Start Charging Input parameter %s, %s, %s over range", v1, v2, v3);
+        printf("\r\n\r\n");
+        return;
+    }
+/*
+    if(_chargingData[gun - 1]->SystemStatus == S_IDLE)
+    {
+        printf("\r\nSet Gun %d Start Charging > Voltage: %4d, Current: %d", gun, (int)_voltage, (int)_current);
+
+        ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.EnableForceCharging = true;
+        ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.StartForceCharging = true;
+        ShmChargerInfo->Control.FCharging[gun - 1].FTargetVoltage = _voltage * 10;
+        ShmChargerInfo->Control.FCharging[gun - 1].FTargetCurrent = _current * 10;
+    }
+    else if(ShmGroupCollection[gun - 1].Role == _GROLE_MASTER)
+    {
+        if(ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.EnableForceCharging)
+        {
+            printf("\r\nSet Gun %d > Voltage: %4d, Current: %d", gun, (int)_voltage, (int)_current);
+            ShmChargerInfo->Control.FCharging[gun - 1].FTargetVoltage = _voltage * 10;
+            ShmChargerInfo->Control.FCharging[gun - 1].FTargetCurrent = _current * 10;
+        }
+        else
+        {
+            printf("\r\nGun %d Force Charging Is Disable", gun);
+        }
+    }
+    else
+    {
+        printf("\r\nGun %d SystemStatus(%d) Is Not Available", gun, _chargingData[gun - 1]->SystemStatus);
+    }
+
+    printf("\r\n\r\n");
+*/
+    bool wait = true;
+    int time = 0;
+    struct timeval _Wait_time;
+    unsigned char PreviousSystemStatus = 0xFF;
+    unsigned short _targetVoltage = 0, _targetCurrent = 0;
+
+    while(wait)
+    {
+        switch(_chargingData[gun - 1]->SystemStatus)
+        {
+            case S_IDLE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_IDLE", gun);
+                    printf("\r\nSet Gun %d Start Charging > Voltage: %4d, Current: %d", gun, (int)_voltage, (int)_current);
+
+                    ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.EnableForceCharging = true;
+                    ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.StartForceCharging = true;
+                    ShmChargerInfo->Control.FCharging[gun - 1].FTargetVoltage = _voltage * 10;
+                    ShmChargerInfo->Control.FCharging[gun - 1].FTargetCurrent = _current * 10;
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_REASSIGN_CHECK:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_REASSIGN_CHECK, Wait For Request Charging", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_REASSIGN:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_REASSIGN, Wait For Grouping", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_PREPARNING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARNING", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_PREPARING_FOR_EV:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARING_FOR_EV", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_PREPARING_FOR_EVSE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARING_FOR_EVSE, Wait For EVSE", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+
+                if(_targetVoltage != (int)_chargingData[gun - 1]->EvBatterytargetVoltage ||
+                    _targetCurrent != (int)_chargingData[gun - 1]->EvBatterytargetCurrent)
+                {
+                    _targetVoltage = (int)_chargingData[gun - 1]->EvBatterytargetVoltage;
+                    _targetCurrent = (int)_chargingData[gun - 1]->EvBatterytargetCurrent;
+                    printf("\r\nGun %d Set Voltage: %4d, Current: %d", gun, _targetVoltage, _targetCurrent);
+                }
+                break;
+
+            case S_CHARGING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_CHARGING", gun);
+                    if(PreviousSystemStatus == 0xFF)
+                    {
+                        _targetVoltage = (int)_chargingData[gun - 1]->EvBatterytargetVoltage;
+                        _targetCurrent = (int)_chargingData[gun - 1]->EvBatterytargetCurrent;
+                        printf("\r\nGun %d Voltage: %4d, Current: %d", gun, _targetVoltage, _targetCurrent);
+
+                        if(ShmChargerInfo->Control.FCharging[gun - 1].FCtrl.bits.EnableForceCharging)
+                        {
+                            printf("\r\nSet Gun %d Force Charging > Voltage: %4d, Current: %d", gun, (int)_voltage, (int)_current);
+                            ShmChargerInfo->Control.FCharging[gun - 1].FTargetVoltage = _voltage * 10;
+                            ShmChargerInfo->Control.FCharging[gun - 1].FTargetCurrent = _current * 10;
+                        }
+                    }
+
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                    gettimeofday(&_Wait_time, NULL);
+                }
+                if(_targetVoltage != (int)_chargingData[gun - 1]->EvBatterytargetVoltage ||
+                    _targetCurrent != (int)_chargingData[gun - 1]->EvBatterytargetCurrent)
+                {
+                    _targetVoltage = (int)_chargingData[gun - 1]->EvBatterytargetVoltage;
+                    _targetCurrent = (int)_chargingData[gun - 1]->EvBatterytargetCurrent;
+                    printf("\r\nGun %d Set Voltage: %4d, Current: %d", gun, _targetVoltage, _targetCurrent);
+                }
+
+                time = GetTimeoutValue(_Wait_time) / uSEC_VAL;
+                if(time >= 3)
+                {
+                    wait = false;
+                    printf("\r\nDone");
+                }
+                break;
+
+            case S_TERMINATING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_TERMINATING", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                wait = false;
+                break;
+
+            case S_COMPLETE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_COMPLETE", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                wait = false;
+                break;
+
+            case S_ALARM:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_ALARM", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                wait = false;
+                break;
+
+            default:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun SystemStatus %d Unknown(%d)", gun, _chargingData[gun - 1]->SystemStatus);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                printf("\r\nGun %d SystemStatus(%d) Is Not Available", gun, _chargingData[gun - 1]->SystemStatus);
+                wait = false;
+                break;
+        }
+
+        char word[128];
+        char newString[7][10];
+        int i,j,ctr;
+
+        memset(word, 0x00, sizeof(word));
+        get_char(word);
+
+        if (strlen(word) == 0)
+        {
+            continue;
+        }
+
+        j=0; ctr=0;
+        strcpy(newString[1], "-1");
+        strcpy(newString[2], "-1");
+        for (i = 0; i <= (strlen(word)); i++)
+        {
+            if (word[i] == ' ' || word[i] == '\0' || word[i] == 10)
+            {
+                newString[ctr][j] = '\0';
+                ctr++;
+                j = 0;
+            }
+            else
+            {
+                newString[ctr][j] = word[i];
+                j++;
+            }
+        }
+
+        if(strcmp(newString[0], "c") == 0)
+        {
+            printf("\r\nStop");
+            wait = false;
+        }
+
+        usleep(100000);
+    }
+
+    printf("\r\n\r\n");
+}
+
+// v1: gun
+void SetGunStopCharging(char *v1)
+{
+    int gun = 0;
+
+    gun = atoi(v1);
+
+    if(gun <= 0 || gun > GENERAL_GUN_QUANTITY)
+    {
+        printf("\r\nGun Stop Charging Input parameter %s over range", v1);
+        printf("\r\n\r\n");
+        return;
+    }
+/*
+    if(_chargingData[gun - 1]->SystemStatus >= S_REASSIGN_CHECK && _chargingData[gun - 1]->SystemStatus <= S_CHARGING)
+    {
+        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+    }
+    else if(ShmGroupCollection[gun - 1].Role == _GROLE_SLAVE)
+    {
+        printf("\r\nSet Group [%02X] Stop", gun - 1);
+        ShmGroupCollection[gun - 1].GroupCtrl.bits.SlavePowerOffRequest = true;
+    }
+    else
+    {
+        printf("\r\nGun %d SystemStatus(%d) Is Not Available", gun, _chargingData[gun - 1]->SystemStatus);
+    }
+
+    printf("\r\n\r\n");
+*/
+
+    bool wait = true;
+    int time = 0;
+    struct timeval _Wait_time;
+    unsigned char PreviousSystemStatus = 0xFF;
+
+    while(wait)
+    {
+        switch(_chargingData[gun - 1]->SystemStatus)
+        {
+            case S_IDLE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_IDLE", gun);
+
+                    if(PreviousSystemStatus == 0xFF)
+                    {
+                        if(ShmGroupCollection[gun - 1].Role == _GROLE_SLAVE)
+                        {
+                            printf("\r\nSet Group [%02X] Stop", gun - 1);
+                            ShmGroupCollection[gun - 1].GroupCtrl.bits.SlavePowerOffRequest = true;
+                        }
+                    }
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    gettimeofday(&_Wait_time, NULL);
+                }
+
+                time = GetTimeoutValue(_Wait_time) / uSEC_VAL;
+                if(time >= 3)
+                {
+                    wait = false;
+                    printf("\r\nDone");
+                }
+                break;
+
+            case S_REASSIGN_CHECK:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_REASSIGN_CHECK, Wait For Request Charging", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_REASSIGN:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_REASSIGN, Wait For Grouping", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_PREPARNING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARNING", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_PREPARING_FOR_EV:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARING_FOR_EV", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_PREPARING_FOR_EVSE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_PREPARING_FOR_EVSE, Wait For EVSE", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_CHARGING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_CHARGING", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+
+                    if(!_chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop)
+                    {
+                        _chargingData[gun - 1]->ChargingStopFlag.bits.ManualStop = true;
+                        printf("\r\nSet Gun %d Stop Charging(ManualStop)", gun);
+                    }
+                }
+                break;
+
+            case S_TERMINATING:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_TERMINATING", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_COMPLETE:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_COMPLETE", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            case S_ALARM:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun %d S_ALARM", gun);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                break;
+
+            default:
+                if(PreviousSystemStatus != _chargingData[gun - 1]->SystemStatus)
+                {
+                    printf("\r\nGun SystemStatus %d Unknown(%d)", gun, _chargingData[gun - 1]->SystemStatus);
+                    PreviousSystemStatus = _chargingData[gun - 1]->SystemStatus;
+                }
+                printf("\r\nGun %d SystemStatus(%d) Is Not Available", gun, _chargingData[gun - 1]->SystemStatus);
+                wait = false;
+                break;
+        }
+
+        char word[128];
+        char newString[7][10];
+        int i,j,ctr;
+
+        memset(word, 0x00, sizeof(word));
+        get_char(word);
+
+        if (strlen(word) == 0)
+        {
+            continue;
+        }
+
+        j=0; ctr=0;
+        strcpy(newString[1], "-1");
+        strcpy(newString[2], "-1");
+        for (i = 0; i <= (strlen(word)); i++)
+        {
+            if (word[i] == ' ' || word[i] == '\0' || word[i] == 10)
+            {
+                newString[ctr][j] = '\0';
+                ctr++;
+                j = 0;
+            }
+            else
+            {
+                newString[ctr][j] = word[i];
+                j++;
+            }
+        }
+
+        if(strcmp(newString[0], "c") == 0)
+        {
+            printf("\r\nStop");
+            wait = false;
+        }
+
+        usleep(100000);
+    }
+
+    printf("\r\n\r\n");
+}
+
+void SetGunExtend(char *v1)
+{
+    int gun = 0;
+
+    gun = atoi(v1);
+
+    if(_chargingData[gun - 1]->SystemStatus == S_CHARGING && ShmGroupCollection[gun - 1].Role == _GROLE_MASTER)
+    {
+        printf("\r\nSet Group [%02X] Extend Capability", gun - 1);
+        ShmGroupCollection[gun - 1].GroupCtrl.bits.MorePowerRequest = true;
+    }
+    else
+    {
+        printf("\r\nGun %d Extend Capability Is Not Available, SystemStatus(%d)", gun, _chargingData[gun - 1]->SystemStatus);
+    }
+
+    printf("\r\n\r\n");
+}
+
+// Gun  TargetV  TargetC  GTargetV  GTargetC   OutputV  OutputC   G_Psu_V  G_Psu_C   Psu 0_V  Psu 0_C   Psu 1_V  Psu 1_C   Psu 2_V  Psu 2_C  ...
+//  X  XXXX.X V  XXX.X A  XXXX.X V   XXX.X A  XXXX.X V  XXX.X A  XXXX.X V  XXX.X A  XXXX.X V  XXX.X A  XXXX.X V  XXX.X A  XXXX.X V  XXX.X A
+void ShowGunOutput(void)
+{
+    byte target = 0;
+    unsigned short voltage = 0, current = 0;
+
+    printf("\r\n Gun  TargetV  TargetC  GTargetV  GTargetC   OutputV  OutputC   G_Psu_V  G_Psu_C   Psu 0_V  Psu 0_C   Psu 1_V  Psu 1_C   Psu 2_V  Psu 2_C  ...");
+
+    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    {
+        target = ShmPsuGrouping->Layout[i];
+
+        // "\r\n  %d  %4d.%d V  %3d.%d A  %4d.%d V   %3d.%d A  %4d.%d V  %3d.%d A  %4d.%d V  %3d.%d A  %4d.%d V  %3d.%d A  %4d.%d V  %3d.%d A"
+        voltage = (unsigned short)(_chargingData[target]->EvBatterytargetVoltage * 10);
+        current = (unsigned short)(_chargingData[target]->EvBatterytargetCurrent * 10);
+        printf("\r\n  %d  %4d.%d V  %3d.%d A", target + 1, (voltage / 10), (voltage % 10), (current / 10), (current % 10));
+
+        voltage = ShmPsuGrouping->GroupOutput[target].GTargetVoltage;
+        current = ShmPsuGrouping->GroupOutput[target].GTargetCurrent;
+        printf("  %4d.%d V   %3d.%d A", (voltage / 10), (voltage % 10), (current / 10), (current % 10));
+
+        voltage = (unsigned short)(_chargingData[target]->PresentChargingVoltage * 10);
+        current = (unsigned short)(_chargingData[target]->PresentChargingCurrent * 10);
+        printf("  %4d.%d V  %3d.%d A", (voltage / 10), (voltage % 10), (current / 10), (current % 10));
+
+        voltage = ShmPsuData->PsuGroup[target].GroupPresentOutputVoltage;
+        current = ShmPsuData->PsuGroup[target].GroupPresentOutputCurrent;
+        printf("  %4d.%d V  %3d.%d A", (voltage / 10), (voltage % 10), (current / 10), (current % 10));
+
+        /*
+        for(int j = 0; j < ShmPsuData->PsuGroup[target].GroupPresentPsuQuantity; j++)
+        {
+            printf("  %4d.%d V  %3d.%d A", (voltage / 10), (voltage % 10), (current / 10), (current % 10));
+        }
+        */
+    }
+    printf("\r\n\r\n");
+}
+
+
+void SetGpio(char *v1, char *v2)
+{
+    int testItem = 0;
+    int testItemLen = 1;
+    int ioOutput = 0;
+    char strTest[32][32] = {"4g"};
+    char strItem[32][32] = {"4G Reset"};
+
+    ioOutput = atoi(v2);
+
+    if(ioOutput < 0)
+    {
+        return;
+    }
+    for(int i = 0; i < testItemLen; i++)
+    {
+        if(strcmp((char *)&strTest[i][0], v1) == 0)
+        {
+            testItem = i + 1;
+            break;
+        }
+    }
+
+    if(testItem != 0)
+    {
+        if(ioOutput)
+        {
+            system("echo 1 > /sys/class/gpio/gpio104/value");
+        }
+        else
+        {
+            system("echo 0 > /sys/class/gpio/gpio104/value");
+        }
+        printf("Set %s %s\n",
+            strItem[testItem - 1], ioOutput > 0 ? "High" : "Low");
+    }
+    else
+    {
+        printf("Gpio Item %s Not Found\n", v1);
+    }
+
+    printf("\r\n");
+}
+
+void ShowStatus(void)
+{
+    for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
+    {
+        printf("\r\nGun %d Status = %d, Available = %d", i + 1, _chargingData[i]->SystemStatus, _chargingData[i]->IsAvailable);
+        printf("\r\nAlarmCode");
+        printf("\r\n Connector = %6s, EvConn = %6s, Remote = %6s",
+            strncmp((char *)_chargingData[i]->ConnectorAlarmCode, "", 6) != 0 ?
+                    (char *)_chargingData[i]->ConnectorAlarmCode : "No Err",
+            strncmp((char *)_chargingData[i]->EvConnAlarmCode, "", 6) != 0 ?
+                    (char *)_chargingData[i]->ConnectorAlarmCode : "No Err",
+            strncmp((char *)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemotenAlarmCode, "", 6) != 0 ?
+                    (char *)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemotenAlarmCode : "No Err");
+    }
+    printf("\r\n");
+
+    printf("\r\nStatus Code Len = %d", ShmSysConfigAndInfo->SysWarningInfo.WarningCount);
+    if(ShmSysConfigAndInfo->SysWarningInfo.WarningCount > 0)
+    {
+        printf("\r\n WarningCode:");
+        for(int i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++)
+        {
+            printf(" %s", (char *)&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0]);
+        }
+    }
+
+    printf("\r\n\r\n");
+}
+
 int main(void)
 {
 	if(InitShareMemory() == FAIL)
@@ -2200,8 +2884,8 @@ int main(void)
 		}
 		else if(strcmp(newString[0], "temp") == 0)
 		{
-		    // 取得 PSU 溫度
-			GetPsuTemp();
+		    // 取得溫度
+		    GetTemperature(newString[1]);
 		}
 		else if(strcmp(newString[0], "acin") == 0)
 		{
@@ -2236,6 +2920,7 @@ int main(void)
 		{
 			GetOrClearId(newString[1]);
 		}
+#if 0
 		else if(strcmp(newString[0], "strchg") == 0)
 		{
 		    //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
@@ -2264,12 +2949,12 @@ int main(void)
             // 槍狀態
             RunUnconditionalCharge(newString[1], newString[2], newString[3], newString[4]);
         }
+#endif
         else if(strcmp(newString[0], "wiring") == 0)
         {
             if(strcmp(newString[1], "-1") != 0 && strcmp(newString[1], "") != 0 &&
                 strcmp(newString[2], "-1") != 0 && strcmp(newString[2], "") != 0)
             {
-                // wiring dispenser_id quantity
                 SetWiringInfo(newString[1], newString[2]);
             }
 
@@ -2306,9 +2991,74 @@ int main(void)
             if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
                 strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
             {
+                printf("Test Control Value = %08X\n",ShmChargerInfo->Control.TestCtrl.CtrlValue);
+                printf ("Input cmd fail ------  tctl [tcmd] [value]\n\n");
+
                 continue;
             }
             SetTestControl(newString[1], newString[2]);
+        }
+        else if(strcmp(newString[0], "group") == 0)
+        {
+            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
+            {
+                ShowGroupingInfo();
+                continue;
+            }
+        }
+        else if(strcmp(newString[0], "gdmd") == 0)
+        {
+            ShowGroupingDemand();
+        }
+        else if(strcmp(newString[0], "gunchg") == 0)
+        {
+            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
+                strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0 ||
+                strcmp(newString[3], "-1") == 0 || strcmp(newString[3], "") == 0)
+            {
+                printf ("Input cmd fail ------  gunchg [gun 1-4] [voltage 0-1000] [current 0-100]\n\n");
+                continue;
+            }
+
+            SetGunStartCharging(newString[1], newString[2], newString[3]);
+        }
+        else if(strcmp(newString[0], "gunstp") == 0)
+        {
+            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
+            {
+                printf ("Input cmd fail ------  gunstp [gun 1-4]\n\n");
+                continue;
+            }
+
+            SetGunStopCharging(newString[1]);
+        }
+        else if(strcmp(newString[0], "gunext") == 0)
+        {
+            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
+            {
+                printf ("Input cmd fail ------  gunext [gun 1-4]\n\n");
+                continue;
+            }
+
+            SetGunExtend(newString[1]);
+        }
+        else if(strcmp(newString[0], "output") == 0)
+        {
+            ShowGunOutput();
+        }
+        else if(strcmp(newString[0], "gio") == 0)
+        {
+            if(strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
+                strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
+            {
+                printf ("Input cmd fail ------  gio [io] [on-off 0-1]\n\n");
+                continue;
+            }
+            SetGpio(newString[1], newString[2]);
+        }
+        else if(strcmp(newString[0], "status") == 0)
+        {
+            ShowStatus();
         }
 		else
 			printf ("%s\n", msg);

+ 3 - 1
EVSE/Projects/DO360/Apps/internalComm.c

@@ -371,6 +371,8 @@ unsigned char Query_Relay_Output(unsigned char fd, unsigned char targetAddr, Rel
 
 			Ret_Buf->relay_event.bits.Gun2_N = (rx[8] >> 0) & 0x01;
 			Ret_Buf->relay_event.bits.Gun2_P = (rx[8] >> 1) & 0x01;
+            Ret_Buf->relay_event.bits.Gun2_Parallel_N = (rx[8] >> 2) & 0x01;
+            Ret_Buf->relay_event.bits.Gun2_Parallel_P = (rx[8] >> 3) & 0x01;
 			result = PASS;
 		}
 	}
@@ -1217,7 +1219,7 @@ unsigned char Config_Led_Color(unsigned char fd, unsigned char targetAddr, Led_C
 
 	for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
 		chksum ^= tx[6 + idx];
-	tx[13] = chksum;
+	tx[12] = chksum;
 
 //	for(int i = 0; i < 13; i++)
 //			printf ("tx = %x \n", tx[i]);

+ 39 - 26
EVSE/Projects/DO360/Apps/internalComm.h

@@ -101,6 +101,19 @@ typedef struct AUXPOWER
 	unsigned char voltage[8];
 }AuxPower;
 
+typedef union
+{
+    unsigned char relay_status;
+    struct
+    {
+        unsigned char Gun_N:1;                      // 0: gun_n off,                1: gun_n on
+        unsigned char Gun_P:1;                      // 0: gun_p off,                1: gun_p on
+        unsigned char Gun_Parallel_N_P:1;           // 0: gun_parallel off,         1: gun_parallel on
+        unsigned char Gun_Parallel_P:1;             // 0: gun_parallel off,         1: gun_parallel on
+        unsigned char res:4;
+    }bits;
+}RBRelayControl;
+
 typedef struct RELAY
 {
 	union
@@ -108,32 +121,32 @@ typedef struct RELAY
 		unsigned char relay_status[8];
 		struct
 		{
-			unsigned char AC_Contactor :1;		//bit 0
-			unsigned char CCS_Precharge :1;	//bit 1
-			unsigned char :1;  				//bit 2 reserved
-			unsigned char :1;					//bit 3 reserved
-			unsigned char :1;					//bit 4 reserved
-			unsigned char :1;					//bit 5 reserved
-			unsigned char :1;					//bit 6 reserved
-			unsigned char :1;					//bit 7 reserved
-
-			unsigned char Gun1_N :1;			//bit 0
-			unsigned char Gun1_P :1;			//bit 1
-			unsigned char Gun1_Parallel_N :1;	//bit 2
-			unsigned char Gun1_Parallel_P :1;	//bit 3
-			unsigned char :1;					//bit 4 reserved
-			unsigned char :1;					//bit 5 reserved
-			unsigned char :1;					//bit 6 reserved
-			unsigned char :1;					//bit 7 reserved
-
-			unsigned char Gun2_N :1;			//bit 0
-			unsigned char Gun2_P :1;			//bit 1
-			unsigned char Gun2_Parallel_N :1;	//bit 2
-			unsigned char Gun2_Parallel_P :1;	//bit 3
-			unsigned char :1;					//bit 4 reserved
-			unsigned char :1;					//bit 5 reserved
-			unsigned char :1;					//bit 6 reserved
-			unsigned char :1;					//bit 7 reserved
+            unsigned char AC_Contactor :1;      //bit 0
+            unsigned char CCS_Precharge :1;     //bit 1
+            unsigned char :1;                   //bit 2 reserved
+            unsigned char :1;                   //bit 3 reserved
+            unsigned char :1;                   //bit 4 reserved
+            unsigned char :1;                   //bit 5 reserved
+            unsigned char :1;                   //bit 6 reserved
+            unsigned char :1;                   //bit 7 reserved
+
+            unsigned char Gun1_N :1;            //bit 0
+            unsigned char Gun1_P :1;            //bit 1
+            unsigned char Gun1_Parallel_N :1;   //bit 2
+            unsigned char Gun1_Parallel_P :1;   //bit 3
+            unsigned char :1;                   //bit 4 reserved
+            unsigned char :1;                   //bit 5 reserved
+            unsigned char :1;                   //bit 6 reserved
+            unsigned char :1;                   //bit 7 reserved
+
+            unsigned char Gun2_N :1;            //bit 0
+            unsigned char Gun2_P :1;            //bit 1
+            unsigned char Gun2_Parallel_N :1;   //bit 2
+            unsigned char Gun2_Parallel_P :1;   //bit 3
+            unsigned char :1;                   //bit 4 reserved
+            unsigned char :1;                   //bit 5 reserved
+            unsigned char :1;                   //bit 6 reserved
+            unsigned char :1;                   //bit 7 reserved
 		}bits;
 	}relay_event;
 }Relay;

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


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


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


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


BIN
EVSE/Projects/DO360/Images/u-boot.img


+ 24 - 16
EVSE/Projects/Noodoe/Apps/main.c

@@ -21,7 +21,7 @@
 #define TMR_IDX_LOGPPRINTOUT			2
 #define TMR_IDX_PROFILE_PREPARE			3
 #define TMR_IDX_PWN_CHANGE				4
-#define TMR_IDX_5						5
+#define TMR_IDX_CHECK_TASK					5
 #define TMR_IDX_6						6
 #define TMR_IDX_7						7
 #define TMR_IDX_8						8
@@ -477,8 +477,6 @@ uint8_t ocpp_get_remotestop(uint8_t gun_index)
 
 void ocpp_set_auth_req(uint8_t status, ...)
 {
-	va_list args;
-
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 		if(ShmOCPP16Data->SpMsg.bits.AuthorizeReq != status)
@@ -2841,6 +2839,8 @@ void checkTask()
 				DEBUG_WARN("OcppBackend watch dog timeout task restart.\n");
 				ShmOCPP16Data->procDogTime =  time((time_t*)NULL);
 				system("pkill OcppBackend");
+				sleep(3);
+				ocpp_process_start();
 			}
 
 			if(system("pidof -s OcppBackend > /dev/null") != 0)
@@ -3373,16 +3373,24 @@ int main(void)
 		//==========================================
 		ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status();
 
-		//==========================================
-		// Check task processing
-		//==========================================
-		if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
-			checkTask();
-
-		//==========================================
-		// Check connection timeout specification
-		//==========================================
-		checkConnectionTimeout();
+		//==============================================
+		// Period check for 10 seconds
+		//==============================================
+		if(DiffTimebWithNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10000)
+		{
+			//==============================================
+			// Check task processing
+			//==============================================
+			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
+				checkTask();
+
+			//==============================================
+			// Check connection timeout specification
+			//==============================================
+			checkConnectionTimeout();
+
+			ftime(&startTime[0][TMR_IDX_CHECK_TASK]);
+		}
 
 		//==========================================
 		// Something need run in Idle mode
@@ -3792,7 +3800,7 @@ int main(void)
 							case START_METHOD_RFID:
 								if((ocpp_get_auth_conf()) ||
 								   (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) ||
-								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)))
+								   (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)))
 								{
 									DEBUG_INFO("ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status);
 									if(ocpp_get_auth_result(gun_index) ||
@@ -4017,7 +4025,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||
@@ -4383,7 +4391,7 @@ int main(void)
 								{
 									if(ocpp_get_auth_conf() ||
 									  (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) ||
-									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) ||
+									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_AUTH]) > 2000)) ||
 									  (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)))
 									{
 										if(ocpp_get_auth_result(gun_index) ||

BIN
EVSE/rootfs/var/www/lang.db


+ 7 - 1
EVSE/rootfs/var/www/log_download.php

@@ -65,6 +65,12 @@ img {
 	}
 
 	function getInfo() {
+		var logCnt;
+
+                do{
+                        logCnt = prompt("<?php echo $lang->showWord("logPackPrompt");?>", 2);
+		}while(isNaN(logCnt) || (logCnt > 6) || (logCnt < 1));
+
 		document.getElementById("loading").style.display="block";
 		// 發送 Ajax 查詢請求並處理
 		var request = new XMLHttpRequest();
@@ -72,7 +78,7 @@ img {
 		var d=new Date();
 		var now=d.getFullYear() + ("00" + (d.getMonth() + 1)).slice(-2) + ("00" + d.getDate()).slice(-2) + ("00" + d.getHours()).slice(-2) + ("00" + d.getMinutes()).slice(-2) + ("00" + d.getSeconds()).slice(-2);
 		// POST 參數須使用 send() 發送
-		var data = "name=";
+		var data = "logCnt=" + logCnt;
 
 		// POST 請求必須設置表頭在 open() 下面,send() 上面
 		request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

+ 3 - 17
EVSE/rootfs/var/www/log_download_action.php

@@ -18,26 +18,12 @@
 		
 		$message = $lang->showWord("message_download_log");
 		chdir('/var/www');
-		//shell_exec('sudo cp /root/charger_buffer_log.db /var/www'.'> /dev/null 2>/dev/null ');	
-//		$output =shell_exec('./run_pack_log.sh ');
 		ob_start();
-		// while (@ ob_end_flush()); // end all output buffers if any
-		// $proc = popen('sudo /var/www/html/run_pack_log.sh', 'r');
-//		echo '<pre>';
-		// while (!feof($proc))
-		// {
-			// echo fread($proc, 512);
-		   // @ flush();
-		// }
-//		echo '</pre>';
-	chdir("/root");
-	exec("'./WebService' 'log'",$output,$return_var);
-//	$SerialNumber=json_decode(trim($output[0]))->{'SerialNumber'};
-//echo date('Ym').$SerialNumber;exit;
-//		shell_exec('zip --password "'.date('Ym').$SerialNumber.'" -r /var/www/log.zip /Storage/');
+		chdir("/root");
+		exec("'./WebService' 'log' ".$_POST['logCnt'], $output, $return_var);
 		ob_end_clean();	
 		
 		echo "<font color=#000fff>".$message."</font>";
 	}
 
-?>
+?>

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