|
@@ -1149,6 +1149,22 @@ uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+uint8_t ocpp_get_maxcharging_profileId()
|
|
|
+{
|
|
|
+ uint8_t result = 0;
|
|
|
+
|
|
|
+ if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
|
|
|
+ {
|
|
|
+ result = ShmOCPP16Data->MaxChargingProfile.ChargingProfileId;
|
|
|
+ }
|
|
|
+ else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
|
|
|
+ {
|
|
|
+ result = ShmOCPP20Data->MaxChargingProfile.id;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
uint8_t ocpp_get_smartcharging_profileId(uint8_t gun_index)
|
|
|
{
|
|
|
uint8_t result = 0;
|
|
@@ -3886,6 +3902,50 @@ int isProfileValid(uint8_t gun_index)
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+int getMaxScheduleStart()
|
|
|
+{
|
|
|
+ int result = -1;
|
|
|
+ struct tm tmScheduleStart;;
|
|
|
+ struct timeb tbScheduleStart;
|
|
|
+
|
|
|
+ if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
|
|
|
+ {
|
|
|
+ if((sscanf((char*)ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.StartSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6))
|
|
|
+ {
|
|
|
+ tmScheduleStart.tm_year -= 1900;
|
|
|
+ tmScheduleStart.tm_mon -= 1;
|
|
|
+ tbScheduleStart.time = mktime(&tmScheduleStart);
|
|
|
+ tbScheduleStart.millitm = 0;
|
|
|
+
|
|
|
+ result = DiffTimebWithNow(tbScheduleStart)/1000;
|
|
|
+ //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Max schedule start date parsing error.\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
|
|
|
+ {
|
|
|
+ if((sscanf((char*)ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].startSchedule, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6))
|
|
|
+ {
|
|
|
+ tmScheduleStart.tm_year -= 1900;
|
|
|
+ tmScheduleStart.tm_mon -= 1;
|
|
|
+ tbScheduleStart.time = mktime(&tmScheduleStart);
|
|
|
+ tbScheduleStart.millitm = 0;
|
|
|
+
|
|
|
+ result = DiffTimebWithNow(tbScheduleStart)/1000;
|
|
|
+ //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DEBUG_WARN("Max schedule start date parsing error.\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
int getScheduleStart(int gun_index)
|
|
|
{
|
|
|
int result = -1;
|
|
@@ -4374,72 +4434,116 @@ void checkChargingProfileLimit(uint8_t gun_index)
|
|
|
uint16_t current_limit;
|
|
|
}previousData[3];
|
|
|
|
|
|
+ uint16_t targetMaxCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
|
|
|
+
|
|
|
if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
|
|
|
{
|
|
|
- if((ocpp_get_smartcharging_profileId(gun_index) > 0) &&
|
|
|
- (((strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom)>0) && (strlen((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo)>0)) ? isProfileValid(gun_index) : ON))
|
|
|
+ // Get profile charging profile limit
|
|
|
+ if((ocpp_get_smartcharging_profileId(gun_index) > 0))
|
|
|
{
|
|
|
- // Checking profile kind
|
|
|
- if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Absolute") == PASS))
|
|
|
+ // Checking limitation
|
|
|
+ for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
|
|
|
{
|
|
|
- // Absolute profile
|
|
|
- if(((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP16Data->SmartChargingProfile[gun_index].TransactionId == ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId)) ||
|
|
|
- (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfilePurpose, "TxProfile") == FAIL))
|
|
|
+ if((getScheduleStart(gun_index) > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
|
|
|
+ ((idx_period == 0) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))
|
|
|
+ )
|
|
|
{
|
|
|
- // Checking limitation
|
|
|
- for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
|
|
|
- {
|
|
|
- if((getScheduleStart(gun_index) > ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
|
|
|
- ((idx_period == 0) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))
|
|
|
- )
|
|
|
- {
|
|
|
- ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
|
|
|
- //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
|
|
|
- }
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
|
|
|
+ //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
|
|
|
}
|
|
|
+ else
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- else if((ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId == 0))
|
|
|
+ else
|
|
|
{
|
|
|
ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
|
|
|
}
|
|
|
+
|
|
|
+ // Get max charging profile limit
|
|
|
+ if((ocpp_get_maxcharging_profileId() > 0))
|
|
|
+ {
|
|
|
+ // Checking limitation
|
|
|
+ for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod);idx_period++)
|
|
|
+ {
|
|
|
+ if((getMaxScheduleStart() > ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) &&
|
|
|
+ ((idx_period == 0) || (ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))
|
|
|
+ )
|
|
|
+ {
|
|
|
+ targetMaxCurrent = (mystrcmp((char*)ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
|
|
|
+ //DEBUG_INFO("targetMaxCurrent on period[%d]: %d\n", idx_period, targetMaxCurrent);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Compare target current is over max current for EVSE limit
|
|
|
+ if(gun_index == 0)
|
|
|
+ {
|
|
|
+ if(ShmCharger->gun_info[gun_index].targetCurrent > targetMaxCurrent)
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = targetMaxCurrent;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((ShmCharger->gun_info[gun_index-1].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > targetMaxCurrent)
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = (targetMaxCurrent - ShmCharger->gun_info[gun_index-1].targetCurrent);
|
|
|
+ }
|
|
|
}
|
|
|
else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
|
|
|
{
|
|
|
- if((ocpp_get_smartcharging_profileId(gun_index) > 0) &&
|
|
|
- //(ocpp_get_profile_req(gun_index) != ON) &&
|
|
|
- (((strlen((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validFrom)>0) && (strlen((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validTo)>0)) ? isProfileValid(gun_index) : ON))
|
|
|
+ // Get profile charging profile limit
|
|
|
+ if((ocpp_get_smartcharging_profileId(gun_index) > 0))
|
|
|
{
|
|
|
- // Checking profile kind
|
|
|
- if((mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfileKind, "Absolute") == PASS))
|
|
|
+ // Checking limitation
|
|
|
+ for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod);idx_period++)
|
|
|
{
|
|
|
- // Absolute profile
|
|
|
- if(((mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose, "TxProfile") == PASS) && (ShmOCPP20Data->SmartChargingProfile[gun_index].transactionId == ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId)) ||
|
|
|
- (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose, "TxProfile") == FAIL))
|
|
|
+ if((getScheduleStart(gun_index) > ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) &&
|
|
|
+ ((idx_period == 0) || (ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))
|
|
|
+ )
|
|
|
{
|
|
|
- // Checking limitation
|
|
|
- for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod);idx_period++)
|
|
|
- {
|
|
|
- if((getScheduleStart(gun_index) > ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) &&
|
|
|
- ((idx_period == 0) || (ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))
|
|
|
- )
|
|
|
- {
|
|
|
- ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit);
|
|
|
- //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
|
|
|
- }
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit);
|
|
|
+ //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
|
|
|
}
|
|
|
+ else
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- else if((ShmOCPP20Data->SmartChargingProfile[gun_index].id == 0) && (ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq != ON))
|
|
|
+ else
|
|
|
{
|
|
|
ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
|
|
|
}
|
|
|
+
|
|
|
+ // Get max charging profile limit
|
|
|
+ if((ocpp_get_maxcharging_profileId() > 0))
|
|
|
+ {
|
|
|
+ // Checking limitation
|
|
|
+ for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod);idx_period++)
|
|
|
+ {
|
|
|
+ if((getMaxScheduleStart() > ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) &&
|
|
|
+ ((idx_period == 0) || (ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))
|
|
|
+ )
|
|
|
+ {
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].limit);
|
|
|
+ //DEBUG_INFO("targetMaxCurrent on period[%d]: %d\n", idx_period, targetMaxCurrent);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Compare target current is over max current for EVSE limit
|
|
|
+ if(gun_index == 0)
|
|
|
+ {
|
|
|
+ if(ShmCharger->gun_info[gun_index].targetCurrent > targetMaxCurrent)
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = targetMaxCurrent;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((ShmCharger->gun_info[gun_index-1].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > targetMaxCurrent)
|
|
|
+ ShmCharger->gun_info[gun_index].targetCurrent = (targetMaxCurrent - ShmCharger->gun_info[gun_index-1].targetCurrent);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0)
|
|
@@ -5764,7 +5868,6 @@ int main(void)
|
|
|
refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]);
|
|
|
refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]);
|
|
|
ocpp_set_auth_req(OFF);
|
|
|
- ocpp_reset_smartcharging_profileId(gun_index);
|
|
|
ocpp_set_profile_req(gun_index, ON);
|
|
|
ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO;
|
|
|
ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;
|