Question-and-Answer Resource for the Building Energy Modeling Community
Get started with the Help page
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Force measure to assign string to field, whether or not the string is valid or invalid?

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?

Force measure to assign string to field, whether or not the string is valid or invalid?

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?

Force measure to assign string to field, whether or not the string is valid or invalid?

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? Energyplus?

Post Script:
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.

Force measure to assign string to field, whether or not the string is valid or invalid?

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?

Post Script:


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.

Force measure to assign string to field, whether or not the string is valid or invalid?

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.