Skip to content

Commit 56884a1

Browse files
authored
Specific endpoint for cluster creation
Uses a specific endpoint to write cluster's metadata and commands to write matrix
1 parent 5c42f52 commit 56884a1

File tree

4 files changed

+208
-85
lines changed

4 files changed

+208
-85
lines changed

NEWS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ NEW FEATURES :
1313
* `createClusterST()`/`editClusterST()` :
1414
- **New properties** (*efficiencywithdrawal*, *penalize-variation-injection*, *penalize-variation-withdrawal*, see list of properties according to study version of Antares with `storage_values_default()`)
1515
- **New optional time series** (cost-injection, cost-withdrawal, cost-level, cost-variation-injection, cost-variation-withdrawal)
16-
* `updateScenarioBuilder()` New type of series "hfl" ("hydro final level", similar to "hydrolevels") is available
17-
* `editBindingConstraint()` : control the dimemnsions of the matrix only if a time series is provided by the user for optimization
16+
* `updateScenarioBuilder()` New type of series "hfl" ("hydro final level", similar to "hydrolevels") is available
17+
* `editBindingConstraint()` : control the dimensions of the matrix only if a time series is provided by the user for optimization
18+
* `.createCluster()` uses a specific endpoint to write cluster's metadata and commands to write matrix
1819

1920

2021
### Breaking changes :

R/createCluster.R

Lines changed: 135 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -307,49 +307,73 @@ createClusterRES <- function(area,
307307

308308
# API block
309309
if (is_api_study(opts)) {
310-
311-
if (cluster_type == "thermal") {
312-
cmd <- api_command_generate(
313-
action = "create_cluster",
314-
area_id = area,
315-
cluster_name = cluster_name,
316-
prepro = prepro_data,
317-
modulation = prepro_modulation,
318-
parameters = params_cluster
319-
)
320-
} else {
321-
cmd <- api_command_generate(
322-
action = "create_renewables_cluster",
323-
area_id = area,
324-
cluster_name = cluster_name,
325-
parameters = params_cluster
326-
)
327-
}
328-
329-
api_command_register(cmd, opts = opts)
330-
`if`(
331-
should_command_be_executed(opts),
332-
api_command_execute(cmd, opts = opts, text_alert = "{.emph create_cluster}: {msg_api}"),
333-
cli_command_registered("create_cluster")
334-
)
335-
336-
if (is.null(time_series)) {
337-
time_series <- matrix(0,8760) #Default
310+
311+
if (!is_api_mocked(opts)) {
312+
thermal_type <- identical(cluster_type, "thermal")
313+
renewables_type <- identical(cluster_type, "renewables")
314+
315+
if (thermal_type) {
316+
suffix_endpoint <- "thermal"
317+
} else if (renewables_type) {
318+
suffix_endpoint <- "renewable"
319+
}
320+
321+
body <- transform_list_to_json_for_createCluster(cluster_parameters = params_cluster, cluster_type = cluster_type)
322+
result <- api_post(opts = opts,
323+
endpoint = file.path(opts[["study_id"]], "areas", area, "clusters", suffix_endpoint),
324+
body = body,
325+
encode = "raw")
326+
cli::cli_alert_success("Endpoint Create {.emph {.strong {suffix_endpoint}}} (properties) {.emph {.strong {cluster_name}}} success"
327+
)
328+
329+
cmd <- NULL
330+
if (renewables_type) {
331+
if (!is.null(time_series)) {
332+
cmd <- api_command_generate(
333+
action = "replace_matrix",
334+
target = sprintf("input/renewables/series/%s/%s/series", area, lower_cluster_name),
335+
matrix = time_series
336+
)
337+
}
338+
}
339+
340+
if (thermal_type) {
341+
thermal_time_series <- list("prepro_data" = list("path" = "input/thermal/prepro/%s/%s/data",
342+
"matrix" = prepro_data
343+
),
344+
"prepro_modulation" = list("path" = "input/thermal/prepro/%s/%s/modulation",
345+
"matrix" = prepro_modulation
346+
),
347+
"thermal_availabilities" = list("path" = "input/thermal/series/%s/%s/series",
348+
"matrix" = time_series)
349+
)
350+
not_null_matrix <- sapply(thermal_time_series, FUN = function(l) {!is.null(l[["matrix"]])})
351+
thermal_time_series <- thermal_time_series[not_null_matrix]
352+
353+
if (length(thermal_time_series) > 0) {
354+
actions <- lapply(
355+
X = seq_along(thermal_time_series),
356+
FUN = function(i) {
357+
list(
358+
target = sprintf(thermal_time_series[[i]][["path"]], area, lower_cluster_name),
359+
matrix = thermal_time_series[[i]][["matrix"]]
360+
)
361+
}
362+
)
363+
actions <- setNames(actions, rep("replace_matrix", length(actions)))
364+
cmd <- do.call(api_commands_generate, actions)
365+
}
366+
}
367+
368+
if (!is.null(cmd)) {
369+
api_command_register(cmd, opts = opts)
370+
`if`(
371+
should_command_be_executed(opts),
372+
api_command_execute(cmd, opts = opts, text_alert = "Writing cluster's series: {msg_api}"),
373+
cli_command_registered("replace_matrix")
374+
)
375+
}
338376
}
339-
340-
currPath <- ifelse(identical(cluster_type, "renewables"), "input/renewables/series/%s/%s/series", "input/thermal/series/%s/%s/series")
341-
cmd <- api_command_generate(
342-
action = "replace_matrix",
343-
target = sprintf(currPath, area, lower_cluster_name),
344-
matrix = time_series
345-
)
346-
api_command_register(cmd, opts = opts)
347-
`if`(
348-
should_command_be_executed(opts),
349-
api_command_execute(cmd, opts = opts, text_alert = "Writing cluster's series: {msg_api}"),
350-
cli_command_registered("replace_matrix")
351-
)
352-
353377
return(invisible(opts))
354378
}
355379

@@ -488,3 +512,72 @@ list_pollutants_values <- function(multi_values = NULL) {
488512
"op5"= multi_values,
489513
"co2"= multi_values)
490514
}
515+
516+
517+
#' Transform a user list to a json object to use in the endpoint of cluster creation
518+
#'
519+
#' @importFrom jsonlite toJSON
520+
#' @importFrom assertthat assert_that
521+
#'
522+
#' @param cluster_parameters a list containing the metadata of the cluster you want to create.
523+
#' @param cluster_type the type of cluster you want to create. Each type has specific values.
524+
#'
525+
#' @return a json object
526+
#' @noRd
527+
transform_list_to_json_for_createCluster <- function(cluster_parameters, cluster_type) {
528+
529+
assert_that(cluster_type %in% c("thermal", "renewables"))
530+
assert_that(inherits(x = cluster_parameters, what = "list"))
531+
532+
if (cluster_type == "thermal") {
533+
cluster_parameters <- list("name" = cluster_parameters[["name"]],
534+
"group" = cluster_parameters[["group"]],
535+
"enabled" = cluster_parameters[["enabled"]],
536+
"mustRun" = cluster_parameters[["must-run"]],
537+
"unitCount" = cluster_parameters[["unitcount"]],
538+
"nominalCapacity" = cluster_parameters[["nominalcapacity"]],
539+
"minStablePower" = cluster_parameters[["min-stable-power"]],
540+
"spinning" = cluster_parameters[["spinning"]],
541+
"minUpTime" = cluster_parameters[["min-up-time"]],
542+
"minDownTime" = cluster_parameters[["min-down-time"]],
543+
"costGeneration" = cluster_parameters[["costgeneration"]],
544+
"marginalCost" = cluster_parameters[["marginal-cost"]],
545+
"spreadCost" = cluster_parameters[["spread-cost"]],
546+
"fixedCost" = cluster_parameters[["fixed-cost"]],
547+
"startupCost" = cluster_parameters[["startup-cost"]],
548+
"marketBidCost" = cluster_parameters[["market-bid-cost"]],
549+
"genTs" = cluster_parameters[["gen-ts"]],
550+
"volatilityForced" = cluster_parameters[["volatility.forced"]],
551+
"volatilityPlanned" = cluster_parameters[["volatility.planned"]],
552+
"lawForced" = cluster_parameters[["law.forced"]],
553+
"lawPlanned" = cluster_parameters[["law.planned"]],
554+
"co2" = cluster_parameters[["co2"]],
555+
"nh3" = cluster_parameters[["nh3"]],
556+
"so2" = cluster_parameters[["so2"]],
557+
"nox" = cluster_parameters[["nox"]],
558+
"pm25" = cluster_parameters[["pm2_5"]],
559+
"pm5" = cluster_parameters[["pm5"]],
560+
"pm10" = cluster_parameters[["pm10"]],
561+
"nmvoc" = cluster_parameters[["nmvoc"]],
562+
"op1" = cluster_parameters[["op1"]],
563+
"op2" = cluster_parameters[["op2"]],
564+
"op3" = cluster_parameters[["op3"]],
565+
"op4" = cluster_parameters[["op4"]],
566+
"op5" = cluster_parameters[["op5"]],
567+
"efficiency" = cluster_parameters[["efficiency"]],
568+
"variableOMCost" = cluster_parameters[["variableomcost"]]
569+
)
570+
} else if (cluster_type == "renewables") {
571+
cluster_parameters <- list("name" = cluster_parameters[["name"]],
572+
"group" = cluster_parameters[["group"]],
573+
"enabled" = cluster_parameters[["enabled"]],
574+
"tsInterpretation" = cluster_parameters[["ts-interpretation"]],
575+
"unitCount" = cluster_parameters[["unitcount"]],
576+
"nominalCapacity" = cluster_parameters[["nominalcapacity"]]
577+
)
578+
}
579+
580+
cluster_parameters <- dropNulls(cluster_parameters)
581+
582+
return(toJSON(cluster_parameters, auto_unbox = TRUE))
583+
}

R/editCluster.R

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -151,59 +151,72 @@ editClusterRES <- function(area,
151151
}
152152

153153
if (is_api_study(opts)) {
154+
thermal_type <- identical(cluster_type, "thermal")
155+
renewables_type <- identical(cluster_type, "renewables")
154156

155157
# update parameters if something else than name
156158
if (length(params_cluster) > 1) {
157-
currPath <- ifelse(identical(cluster_type, "renewables"), "input/renewables/clusters/%s/list/%s", "input/thermal/clusters/%s/list/%s")
158-
writeIni(
159-
listData = params_cluster,
160-
pathIni = sprintf(currPath, area, cluster_name),
161-
opts = opts
162-
)
159+
160+
if (thermal_type) {
161+
suffix_endpoint <- "thermal"
162+
} else if (renewables_type) {
163+
suffix_endpoint <- "renewable"
164+
}
165+
166+
body <- transform_list_to_json_for_createCluster(cluster_parameters = params_cluster, cluster_type = cluster_type)
167+
result <- api_patch(opts = opts,
168+
endpoint = file.path(opts[["study_id"]], "areas", area, "clusters", suffix_endpoint, cluster_name),
169+
body = body,
170+
encode = "raw")
171+
cli::cli_alert_success("Endpoint Edit {.emph {.strong {suffix_endpoint}}} (properties) {.emph {.strong {cluster_name}}} success"
172+
)
163173
}
164174

165-
# update prepro_modulation
166-
if (!identical(cluster_type, "renewables") && !is.null(prepro_modulation)) {
167-
cmd <- api_command_generate(
168-
action = "replace_matrix",
169-
target = sprintf("input/thermal/prepro/%s/%s/modulation", area, lower_cluster_name),
170-
matrix = prepro_modulation
171-
)
172-
api_command_register(cmd, opts = opts)
173-
`if`(
174-
should_command_be_executed(opts),
175-
api_command_execute(cmd, opts = opts, text_alert = "Update cluster's pre-process modulation: {msg_api}"),
176-
cli_command_registered("replace_matrix")
177-
)
175+
cmd <- NULL
176+
177+
if (renewables_type) {
178+
if (!is.null(time_series)) {
179+
cmd <- api_command_generate(
180+
action = "replace_matrix",
181+
target = sprintf("input/renewables/series/%s/%s/series", area, lower_cluster_name),
182+
matrix = time_series
183+
)
184+
}
178185
}
179186

180-
# update prepro_data
181-
if (!identical(cluster_type, "renewables") && !is.null(prepro_data)) {
182-
cmd <- api_command_generate(
183-
action = "replace_matrix",
184-
target = sprintf("input/thermal/prepro/%s/%s/data", area, lower_cluster_name),
185-
matrix = prepro_data
186-
)
187-
api_command_register(cmd, opts = opts)
188-
`if`(
189-
should_command_be_executed(opts),
190-
api_command_execute(cmd, opts = opts, text_alert = "Update cluster's pre-process data: {msg_api}"),
191-
cli_command_registered("replace_matrix")
192-
)
187+
if (thermal_type) {
188+
thermal_time_series <- list("prepro_data" = list("path" = "input/thermal/prepro/%s/%s/data",
189+
"matrix" = prepro_data
190+
),
191+
"prepro_modulation" = list("path" = "input/thermal/prepro/%s/%s/modulation",
192+
"matrix" = prepro_modulation
193+
),
194+
"thermal_availabilities" = list("path" = "input/thermal/series/%s/%s/series",
195+
"matrix" = time_series)
196+
)
197+
not_null_matrix <- sapply(thermal_time_series, FUN = function(l) {!is.null(l[["matrix"]])})
198+
thermal_time_series <- thermal_time_series[not_null_matrix]
199+
200+
if (length(thermal_time_series) > 0) {
201+
actions <- lapply(
202+
X = seq_along(thermal_time_series),
203+
FUN = function(i) {
204+
list(
205+
target = sprintf(thermal_time_series[[i]][["path"]], area, lower_cluster_name),
206+
matrix = thermal_time_series[[i]][["matrix"]]
207+
)
208+
}
209+
)
210+
actions <- setNames(actions, rep("replace_matrix", length(actions)))
211+
cmd <- do.call(api_commands_generate, actions)
212+
}
193213
}
194214

195-
# update series
196-
if (!is.null(time_series)) {
197-
currPath <- ifelse(identical(cluster_type, "renewables"), "input/renewables/series/%s/%s/series", "input/thermal/series/%s/%s/series")
198-
cmd <- api_command_generate(
199-
action = "replace_matrix",
200-
target = sprintf(currPath, area, lower_cluster_name),
201-
matrix = time_series
202-
)
215+
if (!is.null(cmd)) {
203216
api_command_register(cmd, opts = opts)
204217
`if`(
205218
should_command_be_executed(opts),
206-
api_command_execute(cmd, opts = opts, text_alert = "Update cluster's series: {msg_api}"),
219+
api_command_execute(cmd, opts = opts, text_alert = "Updating cluster's series: {msg_api}"),
207220
cli_command_registered("replace_matrix")
208221
)
209222
}

tests/testthat/test-createCluster.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,19 @@ test_that("removeCluster(): check if the expected files are deleted", {
276276

277277
unlink(x = opts$studyPath, recursive = TRUE)
278278
})
279+
280+
281+
# Convert list to body for endpoint ----
282+
test_that("transform_list_to_json_for_createCluster() : body is in an expected format", {
283+
284+
params <- list("unitcount" = 3L, "enabled" = TRUE, "group" = "Gas", "law.forced" = "value")
285+
body <- transform_list_to_json_for_createCluster(cluster_parameters = params, cluster_type = "thermal")
286+
expect_true(inherits(x = body, what = "json"))
287+
expect_equal(sort(names(jsonlite::fromJSON(body))), c("enabled", "group", "lawForced", "unitCount"))
288+
289+
# non-existing property
290+
params <- list("unitcount" = 3L, "enabled" = TRUE, "group" = "Gas", "law.forced" = "value", "fake_property" = "antares")
291+
body <- transform_list_to_json_for_createCluster(cluster_parameters = params, cluster_type = "thermal")
292+
expect_true(inherits(x = body, what = "json"))
293+
expect_equal(sort(names(jsonlite::fromJSON(body))), c("enabled", "group", "lawForced", "unitCount"))
294+
})

0 commit comments

Comments
 (0)