# Utility which takes schedules from the NECB 2015 tables spreadsheet and puts them into a JSON file which somewhat # matches the NECB 2011 schedules.json file. require 'rubyXL' require 'json' class Sched_create # Set a bunch of variables which generally remain static and are added to the new schedulesNECB2015.json file because # that was how they were in the NECB2011 schedules.json file. template = "NECB2015" name = "NECB-" name_pre_mod = [ '', '', '-Electric', '', '', '', '' ] name_post_mod = [ '', '', '', '', '-Cooling', '-Heating', '' ] category = [ 'Occupancy', 'Lighting', 'Equipment', 'Fan', 'Thermostat Setpoint', 'Thermostat Setpoint', 'Service Water Heating' ] units = [ 'FRACTION', 'FRACTION', 'FRACTION', 'ON_OFF', 'TEMPERATURE', 'TEMPERATURE', 'FRACTION' ] day_types = [ 'Default|Wkdy', 'Sat', 'Sun|Hol' ] start_date = "2014-01-01T00:00:00+00:00" end_date = "2014-12-31T00:00:00+00:00" type = "Hourly" notes = nil table_array = [] entry_array = [] json_array = [] refs = [ "assumption" ] # Open Excel file containing schdeules and look for the schedlues worksheet. workbook = RubyXL::Parser.parse("./NECB2015_tables-171121.xlsx") worksheet = workbook['A-8.4.3.2.(1)'] # Determine how many rows are used in the schedules worksheet. Had to do this because there were some nil lines # between each schedule in the worksheet. This would cause the .each do command to break early. sheetlength = worksheet.dimension.ref.row_range.end table_index = 0 # Start looping through each schedule in the worksheet. RubyXL reads a few lines after the end of the schedules in # the worksheet. The -32 is there to make sure that there is actually another schedule (or enough room for one) in # the worksheet thus preventing errors due to manipulating nulls. while table_index < (sheetlength -32) curr_loc = 5 cat_index = 0 # Loop through each category defined above (order of categories should match how they are presented in the worksheet). category.each_with_index do |cat, cat_index| # Build the schedule name using the category and some prefixes and suffixes because the nomenclature was not # consistent. Mostly trying to match what is in the NECB2011 schedules.json file. table_name = name + worksheet[table_index+1][0].value.to_s[-1] + name_pre_mod[cat_index] + "-" + cat + name_post_mod[cat_index] # Loop through each day type: Weekdays/default, Saturdays, and Sundays/holidays. day_types.each do |day_type| line_values = [] values = [] # Need special if statements to handle Fans which are "On" and "Off" in the workbook but BTAP represents as 1 and 0. # Also need to handle when cooling is "off" in the workbook but which BTAP represents as setting the setpoint # really high. The normal case (just a fraction) is at the end if cat == "Fan" worksheet[table_index+curr_loc].cells.drop(1).each do |fan_val| if fan_val.value == "On" line_values << 1.0 else line_values << 0.0 end end elsif name_post_mod[cat_index] == "-Cooling" worksheet[table_index+curr_loc].cells.drop(1).each do |cool_val| if cool_val.value == "Off" line_values << 35 else line_values << cool_val.value end end else worksheet[table_index+curr_loc].cells.drop(1).each { |col_ref| line_values << col_ref.value } end # The workbook lists the schedules started at 1:00 am and ending at 12:00 am (not sure why). OpenStudio # schedules start at 12:00 am and end at 11:00 pm (which makes more sense to me). I'm not sure if the to_f # statements need to be there but I added them anyway so all of the values in the .json file would be to at # least 1 decimal place (like the originial NECB2011 schedules.json file). values << line_values[23].to_f line_values.each { |ln_value| values << ln_value.to_f } values.pop # Put everything for this day in a hash (the order according to the original NECB2011 schedules.json file). entry_array = { "template" => template, "name" => table_name, "category" => cat, "units" => units[cat_index], "day_types" => day_type, "start_date" => start_date, "end_date" => end_date, "type" => type, "notes" => notes, "values" => values } # Add this day's hash to all of the others (I was calling them arrays but they were hashes). json_array << entry_array # Go to the next line for the next day. curr_loc += 1 end # Go to the next line for the next category. curr_loc += 1 end # End of the table set the location of the next table (which starts immediately after the preceding one) table_index += curr_loc-1 end # Add a few hashes to the hash containing all of the schedules in the worksheet. This is to match the formatting # found in the original NECB2011 schedules.json file. table_array = { "tables" => [ "name" => "schedules", "data_type" => "table", "refs" => refs, "table" => json_array ] } # Turn the big hash in memory into a .json format and save it to file. The pretty part is so the json file is nicely # ordered and relatively easy to follow. File.open("./schedulesNECB2015.json","w") do |each_file| each_file.write(JSON.pretty_generate(table_array)) end end