15 Detailed output
15.1 Prerequisites
In this chapter we will focus on how to set and get EnergyPlus simulation outputs using the eplusr package. We will illustrate the manipulation of simulation data using tidyverse, and use ggplot2 to visualize the simulation data
We will be working with the IDF and EPW file that pertains to the U.S. Department of Energy (DOE) Commercial Reference Building and Chicago’s TMY3 respectively.
15.2 Variable dictionary reports
The variable dictionary reports are one of the most important outputs when
working with EnergyPlus simulations. These reports inform EnergyPlus users the
outputs that are available for a specific EnergyPlus simulation. Knowing the
outputs that are available in your model would allow users to identify and
subsequently specify relevant outputs for further analysis. Two data dictionary
reports are produced and they are the meter data dictionary (.mdd
)
file and the report data dictionary (.rdd
) file. The .mdd
file
lists the names of the output meters while the .rdd
file lists the names of
the output variables that are available for the simulation. However, you must
first run the simulation before the available variables and meters can be known.
By setting weather = NULL
, a design day simulation will be run, allowing us to
obtain the .rdd
and .mdd
file without running an annual simulation that can
be time consuming for complex models.
job <- model$run(weather = NULL, dir = tempdir())
## ExpandObjects Started.
## No expanded file generated.
## ExpandObjects Finished. Time: 0.053
## EnergyPlus Starting
## EnergyPlus, Version 9.4.0-998c4b761e, YMD=2023.03.09 00:28
## Could not find platform independent libraries <prefix>
## Could not find platform dependent libraries <exec_prefix>
## Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
##
## Initializing Response Factors
## Calculating CTFs for "STEEL FRAME NON-RES EXT WALL"
## Calculating CTFs for "IEAD NON-RES ROOF"
## Calculating CTFs for "EXT-SLAB"
## Calculating CTFs for "INT-WALLS"
## Calculating CTFs for "INT-FLOOR-TOPSIDE"
....
You can then retrieve the list of available variables and meters with the
function read_rdd()
and the read_mdd()
function respectively. Both functions
return a five column data.table
.
mdd <- job$read_mdd()
mdd
## ══ EnergyPlus Meter Data Dictionary File ═══════════════════════════════════════
## * EnergyPlus version: 9.4.0 (998c4b761e)
## * Simulation started: 2023-03-09 00:28:00
##
## ── Details ─────────────────────────────────────────────────────────────────────
## index reported_time_step report_type
## 1: 1 Zone Meter
## 2: 2 Zone Meter
## 3: 3 Zone Meter
## 4: 4 Zone Meter
....
rdd <- job$read_rdd()
rdd
## ══ EnergyPlus Report Data Dictionary File ══════════════════════════════════════
## * EnergyPlus version: 9.4.0 (998c4b761e)
## * Simulation started: 2023-03-09 00:28:00
##
## ── Details ─────────────────────────────────────────────────────────────────────
## index reported_time_step report_type
## 1: 1 Zone Average
## 2: 2 Zone Average
## 3: 3 Zone Average
## 4: 4 Zone Average
....
To specify an output variable of interest, you can add the name of the variable
and the corresponding reporting frequency to the Output:Variable
object. To
avoid a long list of redundant and unnecessary output variables, you should
first remove all of them.
model$Output_Variable <- NULL
model$Output_Meter <- NULL
You can then use the $add()
method to add your variable output of interest.
The first argument to the $add()
method is a list of EnergyPlus object
definitions where each list is named with a valid class name. In this case, the
relevant EnergyPlus objects for defining output meters (.mdd
) and variables
(.rdd
) are the Output:Meter
and the Output:Variable
objects respectively.
output_list <- list(
Output_Variable = list(
key_value = "*",
Variable_Name = "Site Outdoor Air Drybulb Temperature",
Reporting_Frequency = "Hourly"
),
Output_Variable = list(
key_value = "*",
Variable_Name = "Zone Mean Air Temperature",
Reporting_Frequency = "Hourly"
),
Output_Meter = list(
key_name = "Cooling:Electricity",
Reporting_Frequency = "Hourly"
),
Output_Meter = list(
key_name = "Heating:NaturalGas",
Reporting_Frequency = "Hourly"
)
)
model$add(output_list)
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:682]
## Class: <Output:Variable>
## ├─ 1 : "*", !- Key Value
## │─ 2*: "Site Outdoor Air Drybulb Temperature", !- Variable Name
## └─ 3 : "Hourly"; !- Reporting Frequency
##
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:683]
## Class: <Output:Variable>
....
The above code to add meters and variables can become unnecessarily long if you
are adding multiple objects of the same class (in the above example, the
Output:Meter
and Output:Variable
class. You can take advantage of
data.table
’s :=
operator to assign the object name by reference.
variables <- list(
key_value = "*",
Variable_Name = c(
"Site Outdoor Air Drybulb Temperature",
"Zone Mean Air Temperature"
),
Reporting_Frequency = "Hourly"
)
model$add(Output_Variable := variables)
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:686]
## Class: <Output:Variable>
## ├─ 1 : "*", !- Key Value
## │─ 2*: "Site Outdoor Air Drybulb Temperature", !- Variable Name
## └─ 3 : "Hourly"; !- Reporting Frequency
##
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:687]
## Class: <Output:Variable>
....
Likewise, you can use the $add()
method to add your variable meter of
interest.
meters <- list(
key_name = c(
"Cooling:Electricity",
"Heating:NaturalGas"
),
Reporting_Frequency = "Hourly"
)
# add meter outputs to get hourly time-series energy consumption
model$add(Output_Meter := meters)
## $<NA>
## <IdfObject: 'Output:Meter'> [ID:688]
## Class: <Output:Meter>
## ├─ 1*: "Cooling:Electricity", !- Key Name
## └─ 2 : "Hourly"; !- Reporting Frequency
##
## $<NA>
## <IdfObject: 'Output:Meter'> [ID:689]
## Class: <Output:Meter>
## ├─ 1*: "Heating:NaturalGas", !- Key Name
....
Here is a useful function preprocess_idf()
that you can use to preprocess your
EnergyPlus simulations so that it (1) uses the weather file for the simulation,
(2) presents energy consumption outputs in kWh, and (3) remove all existing
output meters and variables and add the list of meters and variables provided as
arguments to the function.
preprocess_idf <- function(idf, meters, variables) {
# make sure weather file input is respected
idf$SimulationControl$Run_Simulation_for_Weather_File_Run_Periods <- "Yes"
# make sure simulation is not run for sizing periods
idf$SimulationControl$Run_Simulation_for_Sizing_Periods <- "No"
# make sure energy consumption is presented in kWh
if (is.null(idf$OutputControl_Table_Style)) {
idf$add(OutputControl_Table_Style = list("HTML", "JtoKWH"))
} else {
idf$OutputControl_Table_Style$Unit_Conversion <- "JtoKWH"
}
# remove all existing meter and variable outputs
if (!is.null(idf$`Output:Meter`)) {
idf$Output_Meter <- NULL
}
# remove all existing meter and variable outputs
if (!is.null(idf$`Output:Table:Monthly`)) {
idf$`Output:Table:Monthly` <- NULL
}
if (!is.null(idf$`Output:Variable`)) {
idf$Output_Variable <- NULL
}
# add meter outputs to get hourly time-series energy consumption
idf$add(Output_Meter := meters)
# add variable outputs to get hourly zone air temperature
idf$add(Output_Variable := variables)
# make sure the modified model is returned
return(idf)
}
The following code demonstrates the use of the function preprocess_idf()
.
meters <- list(
key_name = c(
"Cooling:Electricity",
"Heating:NaturalGas",
"Heating:Electricity",
"InteriorLights:Electricity",
"ExteriorLights:Electricity",
"InteriorEquipment:Electricity",
"Fans:Electricity",
"Pumps:Electricity",
"WaterSystems:NaturalGas"
),
Reporting_Frequency = "Hourly"
)
variables <- list(
key_value = "*",
Variable_Name = c(
"Site Outdoor Air Drybulb Temperature",
"Site Outdoor Air Relative Humidity"
),
Reporting_Frequency = "Hourly"
)
model <- preprocess_idf(model, meters, variables)
Check if the output variables and meters have been correctly added
model$Output_Variable
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:691]
## Class: <Output:Variable>
## ├─ 1 : "*", !- Key Value
## │─ 2*: "Site Outdoor Air Drybulb Temperature", !- Variable Name
## └─ 3 : "Hourly"; !- Reporting Frequency
##
## $<NA>
## <IdfObject: 'Output:Variable'> [ID:692]
## Class: <Output:Variable>
....
model$Output_Meter
## $<NA>
## <IdfObject: 'Output:Meter'> [ID:682]
## Class: <Output:Meter>
## ├─ 1*: "Cooling:Electricity", !- Key Name
## └─ 2 : "Hourly"; !- Reporting Frequency
##
## $<NA>
## <IdfObject: 'Output:Meter'> [ID:683]
## Class: <Output:Meter>
## ├─ 1*: "Heating:NaturalGas", !- Key Name
....
Before you can explore the outputs, you have to first save the model and run the simulation.
model$save(here("data", "idf", "model_preprocessed.idf"), overwrite = TRUE)
## Replace the existing IDF located at /home/runner/work/r4bes/r4bes/data/idf/model_preprocessed.idf.
job <- model$run(epw, dir = tempdir())
## ExpandObjects Started.
## No expanded file generated.
## ExpandObjects Finished. Time: 0.051
## EnergyPlus Starting
## EnergyPlus, Version 9.4.0-998c4b761e, YMD=2023.03.09 00:28
## Could not find platform independent libraries <prefix>
## Could not find platform dependent libraries <exec_prefix>
## Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
##
## Initializing Response Factors
## Calculating CTFs for "STEEL FRAME NON-RES EXT WALL"
## Calculating CTFs for "IEAD NON-RES ROOF"
## Calculating CTFs for "EXT-SLAB"
## Calculating CTFs for "INT-WALLS"
## Calculating CTFs for "INT-FLOOR-TOPSIDE"
....
You will then be able to extract the output variables and meters that have just been specified.
report <- job$report_data(
name = c(variables$Variable_Name, meters$key_name),
environment_name = "annual"
) %>%
select(datetime, name, value) %>%
pivot_wider(names_from = name, values_from = value)
head(report)
## # A tibble: 6 × 12
## datetime `Site Outdoor Air Dryb…` `Site Outdoor …` `InteriorLight…`
## <dttm> <dbl> <dbl> <dbl>
## 1 2017-01-01 01:00:00 -7.82 72.6 9649498.
## 2 2017-01-01 02:00:00 -11.9 73 9649498.
## 3 2017-01-01 03:00:00 -11.4 73 9649498.
## 4 2017-01-01 04:00:00 -11.1 73 9649498.
## 5 2017-01-01 05:00:00 -10.8 73 9649498.
## 6 2017-01-01 06:00:00 -10.6 73 9649498.
## # … with 8 more variables: `InteriorEquipment:Electricity` <dbl>,
....