Last active
March 15, 2022 13:44
-
-
Save hongyuanjia/6a31b0daec04e9d41d01c6fde0493c6d to your computer and use it in GitHub Desktop.
Construct an EnregyPlus Schedule:Year object from multiple csv files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
read_sch_data <- function(path) { | |
# read meta data | |
meta <- data.table::fread(path, nrows = 4) | |
# get the month number | |
month <- meta[V1 == "IMonth", as.integer(V2)] | |
# get the occu num | |
num <- meta[V1 == "OccuNum", as.integer(V2)] | |
# get the accom type | |
type <- meta[V1 == "AccomType", V2] | |
# read the schedule value | |
data <- data.table::fread(path, skip = 4) | |
data[, DiaryDay_Act := hms::as_hms(DiaryDay_Act)] | |
# get the weekday name from colum name | |
weekday <- names(data)[2L] | |
# get the interval in mins | |
interval <- diff(data$DiaryDay_Act[1:2]) / 60 | |
# store all data | |
list(month = month, num = num, type = type, weekday = weekday, | |
interval = interval, data = data) | |
} | |
create_sch_daily <- function(idf, data, type_limits = "On/Off") { | |
# add an empty Schedule:Day:List object | |
sch <- idf$add( | |
Schedule_Day_List = list( | |
# create schedule name in style 'AccomType_Month_Weekday' | |
sprintf("%s_%s_%s", data$type, month.abb[data$month], data$weekday), | |
type_limits, "No", data$interval | |
) | |
)[[1]] | |
sch$set(c(sch$value(1:4), data$data[[data$weekday]])) | |
sch | |
} | |
create_sch_weekly <- function(idf, name, list_days) { | |
WEEKDAY <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday") | |
# stop if any weekday data is missing | |
if (any(mis_wd <- !WEEKDAY %in% names(list_days))) { | |
stop("Missing schedule for weekday [", paste(WEEKDAY[mis_wd], collapse = ", "), "]") | |
} | |
# create a "AlwaysOff" for weekends, design days and other days | |
# adjust this as you need | |
if (!idf$is_valid_class("Schedule:Day:Interval") || | |
!idf$is_valid_name("AlwaysOff", "Schedule:Day:Interval")) { | |
idf$add(Schedule_Day_Interval = list("AlwaysOff", "On/Off", "No", "Until: 24:00", 0)) | |
} | |
# create a daily schedule | |
idf$add( | |
Schedule_Week_Daily = list( | |
name, | |
"AlwaysOff", | |
list_days$Monday$name(), | |
list_days$Tuesday$name(), | |
list_days$Wednesday$name(), | |
list_days$Thursday$name(), | |
list_days$Friday$name(), | |
"AlwaysOff", | |
"AlwaysOff", | |
"AlwaysOff", "AlwaysOff", | |
"AlwaysOff", "AlwaysOff" | |
) | |
)[[1L]] | |
} | |
create_sch_yearly <- function(idf, name, list_months, type_limits = "Any number") { | |
# get the start and end day for each month | |
start <- lubridate::ymd("2022-01-01") + months(0:11) | |
end <- lubridate::rollforward(start) | |
# combine start day, end day and month schedules | |
data <- data.table::data.table( | |
index = seq_len(12), | |
start = start, end = end, | |
sch = purrr::map(list_months, ~.$name()) | |
) | |
# get the start and end day field value | |
data[, `:=`( | |
start_month = as.list(lubridate::month(start)), | |
start_day = as.list(lubridate::mday(start)), | |
end_month = as.list(lubridate::month(end)), | |
end_day = as.list(lubridate::mday(end)) | |
)] | |
# remove original start and end column since not needed | |
data[, `:=`(start = NULL, end = NULL)] | |
# melt the data based on index column | |
m <- data.table::melt.data.table(data, "index") | |
data.table::setorderv(m, "index") | |
idf$add( | |
Schedule_Year = as.list(c(name, type_limits, m$value)) | |
)[[1L]] | |
} | |
# use the example model distributed with EnergyPlus v8.8 for illustration | |
path_idf <- eplusr::path_eplus_example(8.8, "1ZoneUncontrolled.idf") | |
idf <- eplusr::read_idf(path_idf) | |
# read all schedule data for a certain week | |
path_csv <- list.files("CSV Dir", pattern = ".csv", full.names = TRUE) | |
sch_data <- purrr::map(path_csv, read_sch_data) | |
names(sch_data) <- purrr::map_chr(sch_data, ~.$weekday) | |
# create a daily schedule for each weekday | |
list_days <- purrr::map(sch_data, create_sch_daily, idf = idf) | |
# create a weekly schedule for a month | |
# here use Jan as an example | |
Jan <- create_sch_weekly(idf, "Jan", list_days) | |
# since the sample data is only for Jan, I create schedules for other months by | |
# duplicating Jan sch | |
list_months <- purrr::map(month.abb, ~{ | |
if (. == "Jan") return(Jan) | |
new <- Jan$name() | |
names(new) <- . | |
idf$dup(new)[[1L]] | |
}) | |
# create yearly data using 12 month schedules | |
create_sch_yearly(idf, "Yearly", list_months, "On/Off") | |
#> <IdfObject: 'Schedule:Year'> [ID:72] `Yearly` | |
#> Class: <Schedule:Year> | |
#> +- 01*: "Yearly", !- Name | |
#> |- 02 : "On/Off", !- Schedule Type Limits Name | |
#> |- 03*: "Jan", !- Schedule:Week Name 1 | |
#> |- 04*: 1, !- Start Month 1 | |
#> |- 05*: 1, !- Start Day 1 | |
#> |- 06*: 1, !- End Month 1 | |
#> |- 07*: 31, !- End Day 1 | |
#> |- 08 : "Feb", !- Schedule:Week Name 2 | |
#> |- 09 : 2, !- Start Month 2 | |
#> |- 10 : 1, !- Start Day 2 | |
#> |- 11 : 2, !- End Month 2 | |
#> |- 12 : 28, !- End Day 2 | |
#> |- 13 : "Mar", !- Schedule:Week Name 3 | |
#> |- 14 : 3, !- Start Month 3 | |
#> |- 15 : 1, !- Start Day 3 | |
#> |- 16 : 3, !- End Month 3 | |
#> |- 17 : 31, !- End Day 3 | |
#> |- 18 : "Apr", !- Schedule:Week Name 4 | |
#> |- 19 : 4, !- Start Month 4 | |
#> |- 20 : 1, !- Start Day 4 | |
#> |- 21 : 4, !- End Month 4 | |
#> |- 22 : 30, !- End Day 4 | |
#> |- 23 : "May", !- Schedule:Week Name 5 | |
#> |- 24 : 5, !- Start Month 5 | |
#> |- 25 : 1, !- Start Day 5 | |
#> |- 26 : 5, !- End Month 5 | |
#> |- 27 : 31, !- End Day 5 | |
#> |- 28 : "Jun", !- Schedule:Week Name 6 | |
#> |- 29 : 6, !- Start Month 6 | |
#> |- 30 : 1, !- Start Day 6 | |
#> |- 31 : 6, !- End Month 6 | |
#> |- 32 : 30, !- End Day 6 | |
#> |- 33 : "Jul", !- Schedule:Week Name 7 | |
#> |- 34 : 7, !- Start Month 7 | |
#> |- 35 : 1, !- Start Day 7 | |
#> |- 36 : 7, !- End Month 7 | |
#> |- 37 : 31, !- End Day 7 | |
#> |- 38 : "Aug", !- Schedule:Week Name 8 | |
#> |- 39 : 8, !- Start Month 8 | |
#> |- 40 : 1, !- Start Day 8 | |
#> |- 41 : 8, !- End Month 8 | |
#> |- 42 : 31, !- End Day 8 | |
#> |- 43 : "Sep", !- Schedule:Week Name 9 | |
#> |- 44 : 9, !- Start Month 9 | |
#> |- 45 : 1, !- Start Day 9 | |
#> |- 46 : 9, !- End Month 9 | |
#> |- 47 : 30, !- End Day 9 | |
#> |- 48 : "Oct", !- Schedule:Week Name 10 | |
#> |- 49 : 10, !- Start Month 10 | |
#> |- 50 : 1, !- Start Day 10 | |
#> |- 51 : 10, !- End Month 10 | |
#> |- 52 : 31, !- End Day 10 | |
#> |- 53 : "Nov", !- Schedule:Week Name 11 | |
#> |- 54 : 11, !- Start Month 11 | |
#> |- 55 : 1, !- Start Day 11 | |
#> |- 56 : 11, !- End Month 11 | |
#> |- 57 : 30, !- End Day 11 | |
#> |- 58 : "Dec", !- Schedule:Week Name 12 | |
#> |- 59 : 12, !- Start Month 12 | |
#> |- 60 : 1, !- Start Day 12 | |
#> |- 61 : 12, !- End Month 12 | |
#> \- 62 : 31; !- End Day 12 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment