-
Notifications
You must be signed in to change notification settings - Fork 0
/
time_resolution.Rmd
115 lines (87 loc) · 4.55 KB
/
time_resolution.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
---
title: "Time resolution"
output: html_document
---
```{r setup, include=FALSE}
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:
```{r sessions, echo = F}
# 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')
```
```{r}
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):
```{r}
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:
```{r}
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:
```{r}
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:
```{r}
sum(demand_5$Users*5/60) # in kWh
```
```{r}
sum(demand_15$Users*15/60) # in kWh
```
```{r}
sum(demand_30$Users*30/60) # in kWh
```