forked from EVerest/everest-demo
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request EVerest#88 from US-JOET/migrate_departure_time_cha…
…nges ✨ 🩹⏱️ Migrate departure time patches to the main repo
- Loading branch information
Showing
24 changed files
with
2,560 additions
and
386 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
TAG=0.0.19 | ||
TAG=0.0.20 | ||
|
||
EVEREST_MANAGER_CPUS='1.0' | ||
EVEREST_MANAGER_MEMORY='1024mb' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
|
||
echo "Applying compile-time patches" | ||
|
||
cd / && patch -p0 -i /tmp/demo-patches/enable_iso_dt.patch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
|
||
echo "Applying library patches" | ||
|
||
cd / && patch -p0 -i /tmp/demo-patches/enable_ocpp_logging.patch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/bash | ||
|
||
echo "Applying comm_session_handler_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/comm_session_handler_enabledt.patch | ||
echo "Applying ev_state_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/ev_state_enabledt.patch | ||
echo "Applying iso15118_2_states_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/iso15118_2_states_enabledt.patch | ||
echo "Applying jsevmanager_index_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/jsevmanager_index_enabledt.patch | ||
echo "Applying pyjosev_module_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/pyjosev_module_enabledt.patch | ||
echo "Applying simulator_enabledt.patch" | ||
cd / && patch -p0 -N -i /tmp/demo-patches/simulator_enabledt.patch | ||
|
||
echo "Applying enabled_payment_method_in_python.patch" | ||
cd /ext && patch -p0 -i /tmp/demo-patches/enable_payment_method_in_python.patch | ||
echo "Applying support_payment_in_jsevmanager.patch" | ||
cd /ext/dist/libexec/everest && patch -p1 -i /tmp/demo-patches/support_payment_in_jsevmanager.patch | ||
|
||
cp /tmp/demo-patches/power_curve.py \ | ||
/ext/dist/libexec/everest/3rd_party/josev/iso15118/evcc/states/ | ||
|
||
cp /tmp/demo-patches/enable_evcc_logging.cfg /ext/dist/etc/everest/default_logging.cfg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- /ext/source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/comm_session_handler.py | ||
+++ /ext/dist/libexec/everest/3rd_party/josev/iso15118/evcc/comm_session_handler.py | ||
@@ -114,6 +114,21 @@ | ||
# Once the timer is up, the EV will terminate the communication session. | ||
# A value >= 0 means the timer is running, a value < 0 means it stopped. | ||
self.ongoing_timer: float = -1 | ||
+ | ||
+ # The Charge timer (in seconds) starts running once the EVCC | ||
+ # receives a PowerDeliveryRes with EVSEProcessing set to 'Finished'. | ||
+ # This timer counts up during a charge session, recording the duration. | ||
+ # When a charge session is paused or stopped, the timer is reset. | ||
+ # A value >= 0 means the timer is running, a value < 0 means it stopped. | ||
+ self.charging_session_timer: float = -1 | ||
+ # The end of profile schedule marks the final departure time within | ||
+ # the profile_entry_schedule created for a PowerDeliveryReq. This | ||
+ # value, is used to mark when the 24 entry schedule has terminated. | ||
+ # See ISO 15118-2 Subclause 8.5.2.10 for details | ||
+ self.end_of_profile_schedule: int= -1 | ||
+ self.sim_speed: int = -1 | ||
+ self.departure_time: int = -1 | ||
+ | ||
# Temporarily save the ScheduleExchangeReq, which need to be resent to the SECC | ||
# if the response message's EVSEProcessing field is set to "Ongoing" | ||
self.ongoing_schedule_exchange_req: Optional[ScheduleExchangeReq] = None |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
--- /ext/source/modules/EvseV2G/iso_server.cpp | ||
+++ /ext/source/modules/EvseV2G/iso_server.cpp | ||
@@ -37,6 +37,7 @@ | ||
#define MQTT_MAX_PAYLOAD_SIZE 268435455 | ||
#define V2G_SECC_MSG_CERTINSTALL_TIME 4500 | ||
#define GEN_CHALLENGE_SIZE 16 | ||
+#define CEIL(x, y) (x)/(y) + ((x) % (y) != 0); | ||
|
||
constexpr uint16_t SAE_V2H = 28472; | ||
constexpr uint16_t SAE_V2G = 28473; | ||
@@ -1072,6 +1073,7 @@ | ||
} | ||
res->EVSEProcessing = (iso2_EVSEProcessingType)conn->ctx->evse_v2g_data.evse_processing[PHASE_AUTH]; | ||
|
||
+ | ||
if (conn->ctx->evse_v2g_data.evse_processing[PHASE_AUTH] != iso2_EVSEProcessingType_Finished) { | ||
if (((is_payment_option_contract == false) && (conn->ctx->session.auth_timeout_eim == 0)) || | ||
((is_payment_option_contract == true) && (conn->ctx->session.auth_timeout_pnc == 0))) { | ||
@@ -1130,32 +1132,84 @@ | ||
res->EVSEChargeParameter_isUsed = 0; | ||
res->EVSEProcessing = (iso2_EVSEProcessingType)conn->ctx->evse_v2g_data.evse_processing[PHASE_PARAMETER]; | ||
|
||
+ struct linked_ac_params { | ||
+ float max_current; | ||
+ int64_t voltage; | ||
+ int64_t pmax; | ||
+ }; | ||
+ | ||
+ linked_ac_params sel_params; | ||
+ | ||
/* Configure SA-schedules*/ | ||
if (res->EVSEProcessing == iso2_EVSEProcessingType_Finished) { | ||
/* If processing is finished, configure SASchedule list */ | ||
if (conn->ctx->evse_v2g_data.evse_sa_schedule_list_is_used == false) { | ||
+ int64_t departure_time_duration = req->AC_EVChargeParameter.DepartureTime; | ||
+ | ||
/* If not configured, configure SA-schedule automatically for AC charging */ | ||
if (conn->ctx->is_dc_charger == false) { | ||
/* Determin max current and nominal voltage */ | ||
- float max_current = conn->ctx->basic_config.evse_ac_current_limit; | ||
- int64_t nom_voltage = | ||
+ linked_ac_params default_params; | ||
+ /* Setup default params (before the departure time overrides) */ | ||
+ default_params.max_current = conn->ctx->basic_config.evse_ac_current_limit; | ||
+ default_params.voltage = | ||
conn->ctx->evse_v2g_data.evse_nominal_voltage.Value * | ||
pow(10, conn->ctx->evse_v2g_data.evse_nominal_voltage.Multiplier); /* nominal voltage */ | ||
|
||
/* Calculate pmax based on max current, nominal voltage and phase count (which the car has selected | ||
* above) */ | ||
- int64_t pmax = | ||
- max_current * nom_voltage * | ||
+ default_params.pmax = | ||
+ default_params.max_current * default_params.voltage * | ||
((req->RequestedEnergyTransferMode == iso2_EnergyTransferModeType_AC_single_phase_core) ? 1 : 3); | ||
- populate_physical_value(&conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
+ dlog(DLOG_LEVEL_WARNING, "before adjusting for departure time, max_current %f, nom_voltage %d, pmax %d, departure_duration %d", | ||
+ default_params.max_current, default_params.voltage, | ||
+ default_params.pmax, departure_time_duration); | ||
+ double req_eamount = calc_physical_value(req->AC_EVChargeParameter.EAmount.Value, | ||
+ req->AC_EVChargeParameter.EAmount.Multiplier); | ||
+ dlog(DLOG_LEVEL_WARNING, "Requested departure time %u, requested energy %f", | ||
+ departure_time_duration, req_eamount); | ||
+ if (departure_time_duration == 0) { | ||
+ dlog(DLOG_LEVEL_WARNING, "No departure time specified, not modifying defaults"); | ||
+ sel_params = default_params; | ||
+ } else { | ||
+ dlog(DLOG_LEVEL_WARNING, "Departure time specified, checking to see if we can lower requirements"); | ||
+ int64_t departure_time_duration_hours = departure_time_duration / 3600; | ||
+ float min_hours_to_charge = req_eamount / default_params.pmax; | ||
+ float min_secs_to_charge = min_hours_to_charge * 60 * 60; | ||
+ if (min_secs_to_charge >= departure_time_duration) { | ||
+ dlog(DLOG_LEVEL_WARNING, | ||
+ "Min hours to charge %f, requested departure time in hours %f, pmax is unchanged", | ||
+ min_hours_to_charge, departure_time_duration_hours); | ||
+ sel_params = default_params; | ||
+ } else { | ||
+ /* In general, while computing these values, we use integer division | ||
+ which rounds down. We then check if there is a reminder and add one to round up. | ||
+ The rationale is that, from a user perspective, it is better to finish charging | ||
+ a teeny bit early rather than not provide all the energy requested */ | ||
+ sel_params.pmax = (int)std::ceil(req_eamount / departure_time_duration_hours); | ||
+ sel_params.voltage = default_params.voltage; | ||
+ sel_params.max_current = CEIL(sel_params.pmax, (sel_params.voltage * | ||
+ ((req->RequestedEnergyTransferMode == iso2_EnergyTransferModeType_AC_single_phase_core) ? 1 : 3))); | ||
+ dlog(DLOG_LEVEL_WARNING, | ||
+ "Min hours to charge %f, requested departure time in hours %d, plenty of time to charge", | ||
+ min_hours_to_charge, departure_time_duration_hours); | ||
+ dlog(DLOG_LEVEL_WARNING, "lowering pmax = %d, max_current = %f, pmax float = %f", | ||
+ sel_params.pmax, sel_params.max_current, ((float)req_eamount / (float)departure_time_duration_hours)); | ||
+ } | ||
+ } | ||
+ populate_physical_value(&conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
.PMaxSchedule.PMaxScheduleEntry.array[0] | ||
.PMax, | ||
- pmax, iso2_unitSymbolType_W); | ||
+ sel_params.pmax, iso2_unitSymbolType_W); | ||
} else { | ||
conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
.PMaxSchedule.PMaxScheduleEntry.array[0] | ||
.PMax = conn->ctx->evse_v2g_data.evse_maximum_power_limit; | ||
} | ||
+ if (departure_time_duration == 0) { | ||
+ departure_time_duration = SA_SCHEDULE_DURATION; // one day, per spec | ||
+ } | ||
+ | ||
conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
.PMaxSchedule.PMaxScheduleEntry.array[0] | ||
.RelativeTimeInterval.start = 0; | ||
@@ -1164,7 +1218,7 @@ | ||
.RelativeTimeInterval.duration_isUsed = 1; | ||
conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
.PMaxSchedule.PMaxScheduleEntry.array[0] | ||
- .RelativeTimeInterval.duration = SA_SCHEDULE_DURATION; | ||
+ .RelativeTimeInterval.duration = departure_time_duration; | ||
conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.array[0] | ||
.PMaxSchedule.PMaxScheduleEntry.arrayLen = 1; | ||
conn->ctx->evse_v2g_data.evse_sa_schedule_list.SAScheduleTuple.arrayLen = 1; | ||
@@ -1207,19 +1261,15 @@ | ||
|
||
populate_ac_evse_status(conn->ctx, &res->AC_EVSEChargeParameter.AC_EVSEStatus); | ||
|
||
+ // We have already calculated all of these above, so let's not duplicate code here | ||
/* Max current */ | ||
- float max_current = conn->ctx->basic_config.evse_ac_current_limit; | ||
- populate_physical_value_float(&res->AC_EVSEChargeParameter.EVSEMaxCurrent, max_current, 1, | ||
+ populate_physical_value_float(&res->AC_EVSEChargeParameter.EVSEMaxCurrent, sel_params.max_current, 1, | ||
iso2_unitSymbolType_A); | ||
- | ||
/* Nominal voltage */ | ||
res->AC_EVSEChargeParameter.EVSENominalVoltage = conn->ctx->evse_v2g_data.evse_nominal_voltage; | ||
- int64_t nom_voltage = conn->ctx->evse_v2g_data.evse_nominal_voltage.Value * | ||
- pow(10, conn->ctx->evse_v2g_data.evse_nominal_voltage.Multiplier); | ||
|
||
/* Calculate pmax based on max current, nominal voltage and phase count (which the car has selected above) */ | ||
- int64_t pmax = max_current * nom_voltage * | ||
- ((iso2_EnergyTransferModeType_AC_single_phase_core == req->RequestedEnergyTransferMode) ? 1 : 3); | ||
+ int64_t pmax = sel_params.pmax; | ||
|
||
/* Check the SASchedule */ | ||
if (res->SAScheduleList_isUsed == (unsigned int)1) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- /ext/cache/cpm/libocpp/56452082640eeee05feec42f2f502d6beb8e684c/libocpp/lib/ocpp/v201/charge_point.cpp | ||
+++ /ext/cache/cpm/libocpp/56452082640eeee05feec42f2f502d6beb8e684c/libocpp/lib/ocpp/v201/charge_point.cpp | ||
@@ -3358,7 +3358,7 @@ | ||
} | ||
|
||
void ChargePoint::handle_set_charging_profile_req(Call<SetChargingProfileRequest> call) { | ||
- EVLOG_debug << "Received SetChargingProfileRequest: " << call.msg << "\nwith messageId: " << call.uniqueId; | ||
+ EVLOG_info << "Received SetChargingProfileRequest: " << call.msg << "\nwith messageId: " << call.uniqueId; | ||
auto msg = call.msg; | ||
SetChargingProfileResponse response; | ||
response.status = ChargingProfileStatusEnum::Rejected; | ||
@@ -3383,7 +3383,7 @@ | ||
response.statusInfo = StatusInfo(); | ||
response.statusInfo->reasonCode = "InvalidValue"; | ||
response.statusInfo->additionalInfo = "ChargingStationExternalConstraintsInSetChargingProfileRequest"; | ||
- EVLOG_debug << "Rejecting SetChargingProfileRequest:\n reasonCode: " << response.statusInfo->reasonCode.get() | ||
+ EVLOG_info << "Rejecting SetChargingProfileRequest:\n reasonCode: " << response.statusInfo->reasonCode.get() | ||
<< "\nadditionalInfo: " << response.statusInfo->additionalInfo->get(); | ||
|
||
ocpp::CallResult<SetChargingProfileResponse> call_result(response, call.uniqueId); | ||
@@ -3394,10 +3394,10 @@ | ||
|
||
response = this->smart_charging_handler->validate_and_add_profile(msg.chargingProfile, msg.evseId); | ||
if (response.status == ChargingProfileStatusEnum::Accepted) { | ||
- EVLOG_debug << "Accepting SetChargingProfileRequest"; | ||
+ EVLOG_info << "Accepting SetChargingProfileRequest"; | ||
this->callbacks.set_charging_profiles_callback(); | ||
} else { | ||
- EVLOG_debug << "Rejecting SetChargingProfileRequest:\n reasonCode: " << response.statusInfo->reasonCode.get() | ||
+ EVLOG_info << "Rejecting SetChargingProfileRequest:\n reasonCode: " << response.statusInfo->reasonCode.get() | ||
<< "\nadditionalInfo: " << response.statusInfo->additionalInfo->get(); | ||
} | ||
|
Oops, something went wrong.