I am writing a fairly large measure and I'm having trouble getting the generated idf to have all the fields populated.
The problem is the measure does not set an object field to a string if that string is invalid. For example, if I'm trying to create a Sizing:Plant object with the following fields without having first created the Plant object
Sizing:Plant,
NameOfPlantObjectThatDoesNotExistYet, !- Plant or Condenser Loop Name
Heating, !- Loop Type
82, !- Design Loop Exit Temperature {C}
11.0; !- Loop Design Temperature Difference {deltaC}
the text in the idf file created by the measure looks like this
Sizing:Plant,
, !- Plant or Condenser Loop Name
Heating, !- Loop Type
82, !- Design Loop Exit Temperature {C}
11.0; !- Loop Design Temperature Difference {deltaC}
The solution is very simple. Always create an object before referencing it. However, this is really annoying since you now have to worry about the order of adding objects in the measure.
Is there any way to force the measure to write a value to an object field, even if that string is invalid according to Energyplus?
Failed Fix #1:
Looks like there is no easy way to do what I want. However, I did find a boneheaded way to do it. I start with adding all the idf objects as strings directly from the idf file
# define what happens when the measure is run
def run(workspace, runner, user_arguments)
super(workspace, runner, user_arguments)
# use the built-in error checking
if !runner.validateUserArguments(arguments(workspace), user_arguments)
return false
end
#array to hold new IDF objects
string_objects = []
string_objects << "
AirLoopHVAC,
DOAS, !- Name
DOAS Controllers, !- Controller List Name
DOAS Availability Managers, !- Availability Manager List Name
autosize, !- Design Supply Air Flow Rate {m3/s}
DOAS Branches, !- Branch List Name
, !- Connector List Name
DOAS Air Loop Inlet, !- Supply Side Inlet Node Name
DOAS Return Air Outlet, !- Demand Side Outlet Node Name
DOAS Supply Path Inlet, !- Demand Side Inlet Node Names
DOAS Supply Fan Outlet; !- Supply Side Outlet Node Names
"
.
.
.
MANY MORE OBJECTS ADDED TO string_objects
.
.
.
DONE ADDING OBJECTS
#multiple times so objects that reference other objects can fill fields since all objects exist from first pass
for i in 1..2
string_objects.each do |string_object|
create_object(string_object,workspace)
end
end
return true
end
where the create_objects() function is
def create_object(idf_object_string,workspace)
idf_object_array = idf_object_string.split(/[\n,;]/)
idf_object_array = idf_object_array[1..-3]
field_array = []
idf_object_array.each do |element|
element = element.strip
if !( element.index("!") or element == "")
field_array.push(element)
end
end
object = get_object(field_array[1],field_array[0],workspace)
for i in 2..(field_array.length-1)
object.setString(i-1,field_array[i])
end
return true
end
The first chunk is to extract all the objects field values from the inputted idf_object_string. The second chunk is to create that object. The get_object() function finds the object with a certain name or type, and creates that object if it doesn't exist.
This is kinda boneheaded, but it is working, almost. The first chunk for parsing the idf_object_string in create_object() doesn't work with blank fields, like the Connector List Name in the AirLoopHVAC object named DOAS in the example code above.
Is there an Energyplus measure function I can use to parse the idf_object_string for all its field values, or does anyone know a handy regex way to parse all the field values out? Either way and my workaround will fully work.
Failed Fix #2:
I was looking around the Openstudio sdk documentation and came upon the StrictnessLevel value of the workspace object. The choices are "Final", "Draft", and "None". I've used the strictness level before with
bool openstudio::Workspace::isValid(StrictnessLevel level) const
to find invalid objects in an idf file.
After putting all the objects in the string_objects array, my code for adding the objects to the idf became
workspace.setStrictnessLevel("None".to_StrictnessLevel)
# add all of the strings to workspace to create IDF objects
string_objects.each do |string_object|
idfObject = OpenStudio::IdfObject::load(string_object)
object = idfObject.get
wsObject = workspace.addObject(object)
end
I was hoping setting the strictness level to "None" would allow me to set invalid strings in the fields of the idf objects, but I was unable.
Failed Fix #3:
I tried changing the idd files so that the energyplus measure would think any alphanumeric string is valid for a particular object field. It did not work. I detailed the attempt and results in post Changing the idd file for energyplus measures.