Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ test/*out_*.sqltest
test/*out_*.xml
# TODO: keep updating as new versions are incoming
# We do not commit the current develop version until it's final
test/*_3.9.1*_out.osw
test/*_3.9.1*_out*.status
test/*_3.9.1*_out.sqltest
test/*_3.9.1*_out*.xml
test/*_3.10.0*_out.osw
test/*_3.10.0*_out*.status
test/*_3.10.0*_out.sqltest
test/*_3.10.0*_out*.xml
# Ignore alphas and rcs. CI will force add anything under test/ so it's unaffected
test/*_[0-9].[0-9].[0-9]-*_out*

Expand Down
137 changes: 137 additions & 0 deletions model/simulationtests/output_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# This test aims to test the new **Unique** ModelObjects related to Output
# added in 3.0.0:
# * OutputDiagnostics,
# * OutputDebuggingData,
# * OutputJSON, and
# * OutputTableSummaryReports

import openstudio

from lib.baseline_model import BaselineModel

model = BaselineModel()

# make a 1 story, 100m X 50m, 1 zone building
model.add_geometry(length=100, width=50, num_floors=1, floor_to_floor_height=4, plenum_height=0, perimeter_zone_depth=0)

# add windows at a 40% window-to-wall ratio
model.add_windows(wwr=0.4, offset=1, application_type="Above Floor")

# add thermostats
model.add_thermostats(heating_setpoint=19, cooling_setpoint=26)

# assign constructions from a local library to the walls/windows/etc. in the model
model.set_constructions()

# set whole building space type; simplified 90.1-2004 Large Office Whole Building
model.set_space_type()

# add design days to the model (Chicago)
model.add_design_days()

# In order to produce more consistent results between different runs,
# we sort the zones by names
# (There's only one here, but just in case this would be copy pasted somewhere
# else...)
zones = sorted(model.getThermalZones(), key=lambda z: z.nameString())
z = zones[0]
z.setUseIdealAirLoads(True)

###############################################################################
# OUTPUT:TABLE:MONTHLY #
###############################################################################

# Factory method to creates a OutputTableMonthly from the E+ datasets/StandardReports.idf
# Please use the OutputTableMonthly.validStandardReportNames() static method
# to look up the valid names as it will throw if it cannot find it
standardReportName = next(reversed(sorted(openstudio.model.OutputTableMonthly.validStandardReportNames())))
output_table_monthly = openstudio.model.OutputTableMonthly.fromStandardReports(model, standardReportName)

# You can of course create one yourself
output_table_monthly = openstudio.model.OutputTableMonthly(model)
output_table_monthly.setName("Fan Report")
output_table_monthly.setDigitsAfterDecimal(4)

# To add a group, you can use the convenience method
# bool addMonthlyVariableGroup(std.string variableOrMeterName, std.string aggregationType = "SumOrAverage");

groups = [
# variableOrMeterName, SumOrAverage
("Fan Electricity Energy", "SumOrAverage"),
("Fan Rise in Air Temperature", "SumOrAverage"),
("Fan Electricity Rate", "Maximum"),
("Fan Rise in Air Temperature", "ValueWhenMaximumOrMinimum"),
]
output_table_monthly.addMonthlyVariableGroup(groups[0][0], groups[0][1])

# This will in turn actually use the helper class MonthlyVariableGroup
output_table_monthly.addMonthlyVariableGroup(openstudio.model.MonthlyVariableGroup(groups[1][0], groups[1][1]))

assert output_table_monthly.numberofMonthlyVariableGroups() == 2
# This is a vector of MonthlyVariableGroup
assert len(output_table_monthly.monthlyVariableGroups()) == 2
first_monthly_group = output_table_monthly.monthlyVariableGroups()[0]
# This returns an OptionalMonthlyVariableGroup
first_monthly_group_ = output_table_monthly.getMonthlyVariableGroup(0)
assert first_monthly_group_.is_initialized()
# The equality operator is defined to check for both variableOrMeterName and
# aggregationType
assert first_monthly_group == first_monthly_group_.get()
assert first_monthly_group.variableOrMeterName() == "Fan Electricity Energy"
assert first_monthly_group.aggregationType() == "SumOrAverage"

output_table_monthly.removeMonthlyVariableGroup(1)
output_table_monthly.removeAllMonthlyVariableGroups()

# There is also a batch add
monthly_groups = [openstudio.model.MonthlyVariableGroup(g[0], g[1]) for g in groups]
output_table_monthly.addMonthlyVariableGroups(monthly_groups)
assert output_table_monthly.numberofMonthlyVariableGroups() == 4

###############################################################################
# OUTPUT:TABLE:ANNUAL #
###############################################################################

output_table_annual = openstudio.model.OutputTableAnnual(model)
output_table_annual.setName("Electricity Report")
output_table_annual.setSchedule(model.alwaysOnDiscreteSchedule())
output_table_annual.setFilter("Zone 1")
output_table_annual.resetFilter()

groups = [
# variableorMeterorEMSVariableorField, aggregationType, digitsAfterDecimal
("Electricity:Facility", "SumOrAverage", 3),
("Electricity:Facility", "Maximum", 1),
]

output_table_annual.addAnnualVariableGroup(groups[0][0], groups[0][1], groups[0][2])

# This will in turn actually use the helper class AnnualVariableGroup
output_table_annual.addAnnualVariableGroup(
openstudio.model.AnnualVariableGroup(groups[1][0], groups[1][1], groups[1][2])
)

assert output_table_annual.numberofAnnualVariableGroups() == 2
# This is a vector of AnnualVariableGroup
assert len(output_table_annual.annualVariableGroups()) == 2
first_annual_group = output_table_annual.annualVariableGroups()[0]
# This returns an OptionalAnnualVariableGroup
first_annual_group_ = output_table_annual.getAnnualVariableGroup(0)
assert first_annual_group_.is_initialized()
# The equality operator is defined to check for both variableorMeterorEMSVariableorField and
# aggregationType
assert first_annual_group == first_annual_group_.get()
assert first_annual_group.variableorMeterorEMSVariableorField() == "Electricity:Facility"
assert first_annual_group.aggregationType() == "SumOrAverage"
assert first_annual_group.digitsAfterDecimal() == 3

output_table_annual.removeAnnualVariableGroup(1)
output_table_annual.removeAllAnnualVariableGroups()

# There is also a batch add
annual_groups = [openstudio.model.AnnualVariableGroup(g[0], g[1], g[2]) for g in groups]
output_table_annual.addAnnualVariableGroups(annual_groups)
assert output_table_annual.numberofAnnualVariableGroups() == 2

# save the OpenStudio model (.osm)
model.save_openstudio_osm(osm_save_directory=None, osm_name="in.osm")
145 changes: 145 additions & 0 deletions model/simulationtests/output_tables.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# frozen_string_literal: true

# This test aims to test the new **Unique** ModelObjects related to Output
# added in 3.0.0:
# * OutputDiagnostics,
# * OutputDebuggingData,
# * OutputJSON, and
# * OutputTableSummaryReports

require 'openstudio'
require_relative 'lib/baseline_model'

model = BaselineModel.new

# make a 1 story, 100m X 50m, 1 zone building
model.add_geometry({ 'length' => 100,
'width' => 50,
'num_floors' => 1,
'floor_to_floor_height' => 4,
'plenum_height' => 0,
'perimeter_zone_depth' => 0 })

# add windows at a 40% window-to-wall ratio
model.add_windows({ 'wwr' => 0.4,
'offset' => 1,
'application_type' => 'Above Floor' })

# add thermostats
model.add_thermostats({ 'heating_setpoint' => 19,
'cooling_setpoint' => 26 })

# assign constructions from a local library to the walls/windows/etc. in the model
model.set_constructions

# set whole building space type; simplified 90.1-2004 Large Office Whole Building
model.set_space_type

# add design days to the model (Chicago)
model.add_design_days

# In order to produce more consistent results between different runs,
# we sort the zones by names
# (There's only one here, but just in case this would be copy pasted somewhere
# else...)
zones = model.getThermalZones.sort_by { |z| z.name.to_s }
z = zones[0]
z.setUseIdealAirLoads(true)

###############################################################################
# OUTPUT:TABLE:MONTHLY #
###############################################################################

# Factory method to creates a OutputTableMonthly from the E+ datasets/StandardReports.idf
# Please use the OutputTableMonthly::validStandardReportNames() static method
# to look up the valid names as it will throw if it cannot find it
standardReportName = OpenStudio::Model::OutputTableMonthly.validStandardReportNames.sort.reverse[0]
output_table_monthly = OpenStudio::Model::OutputTableMonthly.fromStandardReports(model, standardReportName)

# You can of course create one yourself
output_table_monthly = OpenStudio::Model::OutputTableMonthly.new(model)
output_table_monthly.setName('Fan Report')
output_table_monthly.setDigitsAfterDecimal(4)

# To add a group, you can use the convenience method
# bool addMonthlyVariableGroup(std::string variableOrMeterName, std::string aggregationType = "SumOrAverage");

groups = [
# variableOrMeterName, SumOrAverage
['Fan Electricity Energy', 'SumOrAverage'],
['Fan Rise in Air Temperature', 'SumOrAverage'],
['Fan Electricity Rate', 'Maximum'],
['Fan Rise in Air Temperature', 'ValueWhenMaximumOrMinimum'],
]
output_table_monthly.addMonthlyVariableGroup(groups[0][0], groups[0][1])

# This will in turn actually use the helper class MonthlyVariableGroup
output_table_monthly.addMonthlyVariableGroup(OpenStudio::Model::MonthlyVariableGroup.new(groups[1][0], groups[1][1]))

raise unless output_table_monthly.numberofMonthlyVariableGroups == 2
# This is a vector of MonthlyVariableGroup
raise unless output_table_monthly.monthlyVariableGroups.size == 2
first_monthly_group = output_table_monthly.monthlyVariableGroups.first
# This returns an OptionalMonthlyVariableGroup
first_monthly_group_ = output_table_monthly.getMonthlyVariableGroup(0)
raise unless first_monthly_group_.is_initialized
# The equality operator is defined to check for both variableOrMeterName and
# aggregationType
raise unless first_monthly_group == first_monthly_group_.get
raise unless first_monthly_group.variableOrMeterName == 'Fan Electricity Energy'
raise unless first_monthly_group.aggregationType == 'SumOrAverage'

output_table_monthly.removeMonthlyVariableGroup(1)
output_table_monthly.removeAllMonthlyVariableGroups

# There is also a batch add
monthly_groups = groups.map { |g| OpenStudio::Model::MonthlyVariableGroup.new(g[0], g[1]) }
output_table_monthly.addMonthlyVariableGroups(monthly_groups)
raise unless output_table_monthly.numberofMonthlyVariableGroups == 4

###############################################################################
# OUTPUT:TABLE:ANNUAL #
###############################################################################

output_table_annual = OpenStudio::Model::OutputTableAnnual.new(model)
output_table_annual.setName("Electricity Report")
output_table_annual.setSchedule(model.alwaysOnDiscreteSchedule)
output_table_annual.setFilter("Zone 1")
output_table_annual.resetFilter

groups = [
#variableorMeterorEMSVariableorField, aggregationType, digitsAfterDecimal
['Electricity:Facility', 'SumOrAverage', 3],
['Electricity:Facility', 'Maximum', 1],
]

output_table_annual.addAnnualVariableGroup(groups[0][0], groups[0][1], groups[0][2])

# This will in turn actually use the helper class AnnualVariableGroup
output_table_annual.addAnnualVariableGroup(OpenStudio::Model::AnnualVariableGroup.new(groups[1][0], groups[1][1], groups[1][2]))

raise unless output_table_annual.numberofAnnualVariableGroups == 2
# This is a vector of AnnualVariableGroup
raise unless output_table_annual.annualVariableGroups.size == 2
first_annual_group = output_table_annual.annualVariableGroups.first
# This returns an OptionalAnnualVariableGroup
first_annual_group_ = output_table_annual.getAnnualVariableGroup(0)
raise unless first_annual_group_.is_initialized
# The equality operator is defined to check for both variableorMeterorEMSVariableorField and
# aggregationType
raise unless first_annual_group == first_annual_group_.get
raise unless first_annual_group.variableorMeterorEMSVariableorField == 'Electricity:Facility'
raise unless first_annual_group.aggregationType == 'SumOrAverage'
raise unless first_annual_group.digitsAfterDecimal == 3

output_table_annual.removeAnnualVariableGroup(1)
output_table_annual.removeAllAnnualVariableGroups

# There is also a batch add
annual_groups = groups.map { |g| OpenStudio::Model::AnnualVariableGroup.new(g[0], g[1], g[2]) }
output_table_annual.addAnnualVariableGroups(annual_groups)
raise unless output_table_annual.numberofAnnualVariableGroups == 2
Comment on lines +49 to +143

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fully demo the extensible API.


# save the OpenStudio model (.osm)
model.save_openstudio_osm({ 'osm_save_directory' => Dir.pwd,
'osm_name' => 'in.osm' })
13 changes: 13 additions & 0 deletions model_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,19 @@ def test_output_objects_2_osm
result = sim_test('output_objects_2.osm')
end

def test_output_tables_rb
result = sim_test('output_tables.rb')
end

def test_output_tables_py
result = sim_test('output_tables.py')
end

# TODO: To be added in the next official release after: 3.9.0
# def test_output_tables_osm
# result = sim_test('output_tables.osm')
# end

Comment on lines +1354 to +1366

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New Ruby + Python test, with a TODO

def test_performanceprecisiontradeoffs_rb
result = sim_test('performanceprecisiontradeoffs.rb')
end
Expand Down