library(BMRSr)
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Introduction

The BMRSr package provides a number of wrapper functions to make the Balancing Mechanism Reporting Service (BMRS) API provided by ELEXON easier to use. There's a massive repository of very useful and interesting data held in BMRS, but the API itself is not particular intuitive, and can result in the user needing to repeat lots of steps in order to retrieve and the clean the data. This package is an effort to automate those boring steps, making it easier for the user to retrieve the data for their analysis.

The first step in using the BMRS API is to read the documentation currently available: Balancing Mechanism Reporting System API. This document tells you all of the available data items and what you can expect to get back. I've tried to include a couple of helper functions to list all data items, find what parameters you need for specific data items, but there's a lot so this document will always be more detailed.

Second, to actually access the BMRS API, you'll need an API key. These are freely available by signing up through the ELEXON Portal: ELEXON portal.

Structure

Querying the BMRS API can be broken down into 4 parts:

So, all together, we need to generate and send a request, get a response back and then parse it.

End-to-end

To do all of these steps in one go and just get back the parsed response, use the full_request() function. We'll go into a bit more detail about what exactly this function does, but it will essentially just builds the request, send it, clean the received data and then return it.

To use the full_request() function, you'll need to provide a few things:

Building and Sending Requests

Building requests

Building your API request is done through the build_call() function. Because there are three different types of data items held in BMRS, the build_call actually calls one of the three different functions to produce the API request needed for your data item. On the surface of it however, build_call will handle all of that for you.

The build_call() function has a few required arguments:

Aside from the required arguments, build_call() has some further optional arguments:

Sending requests

The sending of the API requests is done via the send_request() function.This function is essentially a wrapper to the httr::GET() function with a couple of changes to the parameters. The arguments for send_request() are:

The send_request() function will then return a response() object, with an added $data_item attribute. This data item value will be the data item that was specified in the request list (if one was specified).

Parsing and Cleaning

Parsing the response object returned from the send_request() function is handled by the parse_response() function. This will take the response object, extract the returned data and then do some cleaning.

The parameters for parse_response() are:

Depending on what format you specified, this function will either return a tibble (csv) or a list (xml). And there you have it, your complete API request and response!

Everything else...

In addition to the basic workflow of build, send, parse/clean, the package also provides some utility functions:

A Practical Example

Now we understand the workflow associated with an API request, let's do an example.

We'll do it twice, once just using the full_request() function, and then again using the functions provided for each step to ensure we know what's going on under the hood.

In this example, we'll get some generation data by fuel type between the dates of 1 July 2019 and 3 July 2019 and then plot it using ggplot2. The dataset used is available in the package as generation_dataset_example.

full_request() approach

First things first, let's create a variable to hold our API key...

api_key <- "your_api_key_here"

Next, we've inspected the BMRS API documentation and found that we want the "FUELINST" data item. Let's find out what parameters we need to provide for this data item...

get_parameters("FUELINST")

So we've got to provide from_datetime and to_datetime. Now let's create our request...

generation_data <- full_request(data_item = "FUELINST",
                                api_key = api_key,
                                from_datetime = "01 07 2019 00:00:00",
                                to_datetime = "03 07 2019 00:00:00",
                                parse = TRUE,
                                clean_dates = TRUE)

Step approach

Again, let's create a variable to hold our API key and find out what parameters we need for our "FUELINST" data item...

api_key <- "your_api_key_here"

get_parameters("FUELINST")

Next, let's build our call...

generation_data_request <- build_call(data_item = "FUELINST",
                                      api_key = api_key,
                                      from_datetime = "01 07 2019 00:00:00",
                                      to_datetime = "03 07 2019 00:00:00",
                                      service_type = "csv")

This is equivalent but shorter than...

get_data_item_type("FUELINST")
#This tells us which build_x_call() function to use

generation_data_request <- build_legacy_call(data_item = "FUELINST",
                                             api_key = api_key,
                                             from_datetime = "01 07 2019 00:00:00",
                                             to_datetime = "03 07 2019 00:00:00",
                                             service_type = "csv")

Now we've got our request, we can send it...

generation_data_response <- send_request(request = generation_data_request)

And then parse it...

generation_data <- parse_response(response = generation_data_response,
                                  format = "csv",
                                  clean_dates = TRUE)

Linking all these together using the pipe, we'd get...

generation_data <- build_call(data_item = "FUELINST",
                              api_key = api_key,
                              from_datetime = "01 07 2019 00:00:00",
                              to_datetime = "03 07 2019 00:00:00",
                              service_type = "csv") %>%
  send_request() %>%
  parse_response()

Plotting

Now we've got the data, we can convert the dataset to the tidy format and then make a plot...

generation_data <- generation_dataset_example
#Load the libraries for a bit more cleaning and then plotting...
library(ggplot2, quietly = TRUE, warn.conflicts = FALSE)
library(tidyr, quietly = TRUE, warn.conflicts = FALSE)
library(dplyr, quietly = TRUE, warn.conflicts = FALSE)

#Change the fuel types from columns to a grouping (tidy format)
generation_data <- generation_data %>%
  dplyr::mutate(settlement_period = as.factor(settlement_period)) %>%
  tidyr::gather(key = "fuel_type", value = "generation_mw", ccgt:intnem)

#Make a line graph of the different generation types
ggplot2::ggplot(data = generation_data, aes(x = spot_time, y = generation_mw, colour = fuel_type)) +
  ggplot2::geom_line()


ARawles/BMRSr documentation built on Feb. 1, 2023, 12:11 p.m.