5

OS measure - object list from CSV

Is there a way to parse a list of OS objects from a CSV file and create an array or hash in Ruby? I would like to create a custom list of thermal zones in an OS measure to loop through. Also, how would I path the file location? I have seen other measures on the BCL reference additional files in a 'resources' sub-folder located alongside the measure, but I can't quite discern the correct syntax.

Lyle K's avatar
2.2k
Lyle K
asked 2016-01-27 00:58:58 -0500
__AmirRoth__'s avatar
4.4k
__AmirRoth__
updated 2017-08-05 08:08:26 -0500
edit flag offensive 0 remove flag close merge delete

Comments

add a comment see more comments

3 Answers

7

You can put your zones.csv into a resources subfolder indeed, this way it will stay with your measure (it seems that you can only have measure.rb and measure.xml at the root of your measure folder).

In your zones.csv:

ZoneName
Zone 1
Zone 2
Zone 3

then in your measure:

require 'csv'
# File.dirname(__FILE__) points to the location of the current file, so your `measure.rb`
zones = CSV.table(File.dirname(__FILE__) + '/resources/zones.csv')
#

At this point if you check the headers:

[1] (main)> zones.headers
 => [:zonename]

Then you can do a bunch of stuff, like you can loop on each and grab the thermal zone associated with it

zones.each do |row|
    zonename = row[:zonename]
    zone = model.getThermalZoneByName(zonename)
    if zone.empty?
        puts "couldn't find zone named #{zonename}"
    else
        zone = zone.get
        # Do something else
    end
end

Or if it's easier you can always load all the zone name in a more familiar array object:

# Create empty array to store the zone names
 zone_names = []
 zones.each{|row| zone_names << row[:zonename]}
Julien Marrec's avatar
29.7k
Julien Marrec
answered 2016-01-27 03:14:42 -0500, updated 2016-01-27 08:04:07 -0500
edit flag offensive 0 remove flag delete link

Comments

Thanks @Julien Marrec , this is very helpful! Can you elaborate on the code section under 'At this point if you check the headers:' ?

Lyle K's avatar Lyle K (2016-01-27 12:11:00 -0500) edit

If you are using an interactive prompt you should just call zones.headers. If you want to double check stuff in a measure you should call puts zones.headers. Otherwise just skip it.

Julien Marrec's avatar Julien Marrec (2016-01-27 17:02:16 -0500) edit
add a comment see more comments
5

Adding to @Julien Marrec's answer:

There's not currently a path argument available to OS measures, but you can approximate that function with a simple string argument:

#make an argument for location of .csv file
csv_file_path = OpenStudio::Ruleset::OSArgument::makeStringArgument("csv_file_path",true)
csv_file_path.setDefaultValue("C:\Users\Eric\Desktop\zones.csv")
args << csv_file_path

Then in the run section, apply that string to a variable that you pass into the CSV method of your choice.

ericringold's avatar
10.6k
ericringold
answered 2016-01-27 08:28:23 -0500
edit flag offensive 0 remove flag delete link

Comments

Path arguments are coming in PAT 2.0!

macumber's avatar macumber (2016-01-27 11:20:35 -0500) edit

So hyped for PAT 2.0! :)

ericringold's avatar ericringold (2016-01-27 11:29:23 -0500) edit
add a comment see more comments
1

Just to through in more options. If your list isn't going to be too long, you can have a string argument that expects comma separated values in it, instead of using an external file.

Then in the measure you parse it apart using code like this.

array_from_arg = arg.split(',')

Here is another option that is possible but not really recommended - The arguments section of the measure can loop through zones and make a bool argument for each zone. Then you can check the zones you want included. This isn't ideal because having a variable/unknown number of arguments for a measure can cause issues with large scale analysis, and if you have a really big model this may blow up. If intended to used only with apply measures now, then this could be ok.

David Goldwasser's avatar
20.4k
David Goldwasser
answered 2016-01-27 09:47:48 -0500, updated 2016-01-27 09:51:12 -0500
edit flag offensive 0 remove flag delete link

Comments

Thanks for the additional suggestions, I saw this post where you had previously described these approaches (and others). I was able to successfully implement both methods you describe above, however they aren't the most feasible alternatives when you have many objects (like thermal zones). Managing a specific list of objects (in a CSV) to apply a measure to has great utility; we were routinely doing this using the SDK with python.

Lyle K's avatar Lyle K (2016-01-27 12:30:06 -0500) edit

That being said, it would still be great to have multiple choice arguments available to measures with less trickery. There are other scenarios where this is can be very useful.

Lyle K's avatar Lyle K (2016-01-27 12:32:40 -0500) edit
add a comment see more comments