knitr::opts_chunk$set(echo = TRUE, message = F, warning = F, error = F, fig.width = 9) library(evsim) library(dplyr) library(lubridate)
Functions simulate_sessions()
, get_demand()
or get_occupancy()
requires a parameter called resolution
, which defines the minutes between a time-slot and the following one.
For example, if resolution = 15
, the charging sessions simulated during 4 PM of a specific day will start at 16:00
, 16:15
, 16:30
or 16:45
, but not during any time between these time-slots. However, the connection duration of every session can have any value, so the session can finish at 16:22
for instance. The same concept is applied to the charging times.
Therefore, the function get_demand
gives the average charging power during a certain time-slot. If we use a resolution = 15
, a demand of 55kW for time-slot 16:30
means that between 16:30
and 16:45
it has been consumed the energy corresponding to an average power of 55 kW (so 55ยท15/60=13.75 kWh). This can modify the power profile of sessions that stop charging at a time between time-slots. For example, considering a resolution = 15
and a session charging at 10kW from 16:30
to 16:55
, the demand of time-slot 16:30
will be 10kW but the demand of time-slot 16:45
will decrease to 6.67 kW (charging only 3/4 parts of the time-slot). The "real" power profile of the session is a constant power step of 10kW, but the demand profile obtained with a resolution = 15
does not. To obtain a more accurate power profile of the session, the resolution
parameter should be set to higher resolutions (until a maximum of 1 minute).
Finally, note that the resolution
parameter of time-series functions (i.e. get_demand()
and get_n_connections()
) does not have to correspond necessarily to the resolution
of simulated sessions, even though it would not have much sense to obtain the time-series demand in a lower resolution (longer time intervals) than sessions since we loose accuracy on the power profile.
Let's see and example simulating 10 charging sessions with a resolution
of 30 minutes:
# Required parameters first ev_model <- evsim::california_ev_model sessions_day <- tibble( time_cycle = ev_model$models$time_cycle, n_sessions = c(10, 10) ) user_profiles <- get_user_profiles_distribution(ev_model) charging_powers <- tibble( power = c(3.7, 7.3, 11), ratio = c(0.2, 0.4, 0.4) ) # Sessions simulation set.seed(123) sessions <- simulate_sessions( ev_model, sessions_day, user_profiles, charging_powers, dmy("31/01/2023"), resolution = 30 ) %>% mutate(Profile = 'Users')
sessions %>% select_if(is.timepoint) %>% mutate_all(format, "%d/%m/%Y %H:%M") %>% knitr::kable()
If we calculate the aggregated demand of the above simulated sessions with a resolution
of 5
, 15
and 30
, the resulting power profile loses accuracy when we decrease the time resolution (so higher time intervals):
demand_5 <- sessions %>% get_demand(resolution = 5) demand_15 <- sessions %>% get_demand(resolution = 15) demand_30 <- sessions %>% get_demand(resolution = 30)
Then we can create a common object to compare the three vectors of EV demand, making use of dplyr::left_join
to join by datetime
and tidyr::fill
to fill the gaps with the previous exisiting power:
demand_comparison <- demand_5 %>% rename(`5-minute resolution` = Users) %>% left_join( rename(demand_15, `15-minute resolution` = Users) ) %>% left_join( rename(demand_30, `30-minute resolution` = Users) ) %>% tidyr::fill(-datetime, .direction = 'down') demand_comparison %>% plot_ts(stepPlot = T, strokeWidth = 2, ylab = "EV demand (kW)")
The power profile with a resolution of 5 minutes represents in a higher accuracy when sessions start and finish. If we zoom-in, we can see clearly that the average power profile really depends on the time resolution:
demand_comparison %>% filter( datetime >= dmy_h("31/01/2023 16", tz = ev_model$metadata$tzone), datetime < dmy_h("31/01/2023 19", tz = ev_model$metadata$tzone) ) %>% plot_ts(stepPlot = T, strokeWidth = 2, ylab = "EV demand (kW)")
However, the total area of the three lines (energy consumed) corresponds to the same value since the power values are the average power of every time-slot whatever the resolution is:
sum(demand_5$Users*5/60) # in kWh
sum(demand_15$Users*15/60) # in kWh
sum(demand_30$Users*30/60) # in kWh
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.