Skip to content

Commit

Permalink
Merge pull request #999 from NREL/latest-os-hpxml
Browse files Browse the repository at this point in the history
Latest OS-HPXML
  • Loading branch information
joseph-robertson committed Nov 1, 2022
2 parents 5f7a154 + 29784b2 commit 0ae1158
Show file tree
Hide file tree
Showing 30 changed files with 1,268 additions and 643 deletions.
1 change: 1 addition & 0 deletions project_testing/testing_baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ workflow_generator:
include_timeseries_end_use_consumptions: true
include_timeseries_emissions: true
include_timeseries_total_loads: false
timeseries_timestamp_convention: end
output_variables:
- name: Zone People Occupant Count

Expand Down
1 change: 1 addition & 0 deletions project_testing/testing_upgrades.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ workflow_generator:
include_timeseries_end_use_consumptions: true
include_timeseries_emissions: true
include_timeseries_total_loads: false
timeseries_timestamp_convention: end
output_variables:
- name: Zone People Occupant Count

Expand Down
2 changes: 2 additions & 0 deletions resources/hpxml-measures/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

__New Features__
- **Breaking Change**: Replaces `FrameFloors/FrameFloor` with `Floors/Floor`.
- **Breaking Change**: Replaces `WallType/StructurallyInsulatedPanel` with `WallType/StructuralInsulatedPanel`.
- **Breaking change**: Replaces `SoftwareInfo/extension/SimulationControl/DaylightSaving/Enabled` with `Building/Site/TimeZone/DSTObserved`.
- **Breaking Change**: Replaces `StandbyLoss` with `StandbyLoss[Units="F/hr"]/Value` for an indirect water heater.
- **Breaking Change**: Replaces `BranchPipingLoopLength` with `BranchPipingLength` for a hot water recirculation system.
Expand All @@ -19,6 +20,7 @@ __New Features__
- EnergyPlus modeling changes:
- Switches Kiva foundation model timestep from 'Hourly' to 'Timestep'; small increase in runtime for sub-hourly simulations.
- Annual/timeseries outputs:
- Allows timeseries timestamps to be start or end of timestep convention; **Breaking change**: now defaults to start of timestep.
- Adds annual emission outputs disaggregated by end use; timeseries emission outputs disaggregated by end use can be requested.
- Allows generating timeseries unmet hours for heating and cooling.
- Allows CSV timeseries output to be formatted for use with the DView application.
Expand Down
52 changes: 26 additions & 26 deletions resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.0</schema_version>
<name>hpxm_lto_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>e2eebf1e-46b9-4960-af1f-75ff9df120ad</version_id>
<version_modified>20221011T222505Z</version_modified>
<version_id>68459901-e514-4273-9c46-a9a6449243cf</version_id>
<version_modified>20221018T164334Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -409,12 +409,6 @@
<usage_type>test</usage_type>
<checksum>03FE784E</checksum>
</file>
<file>
<filename>test_simcontrols.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>C198979C</checksum>
</file>
<file>
<filename>test_lighting.rb</filename>
<filetype>rb</filetype>
Expand Down Expand Up @@ -451,12 +445,6 @@
<usage_type>test</usage_type>
<checksum>B13FEA8C</checksum>
</file>
<file>
<filename>output.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>0D0399FA</checksum>
</file>
<file>
<filename>weather.rb</filename>
<filetype>rb</filetype>
Expand Down Expand Up @@ -564,35 +552,47 @@
<usage_type>resource</usage_type>
<checksum>5ED1C14F</checksum>
</file>
<file>
<filename>hpxml_schema/HPXMLBaseElements.xsd</filename>
<filetype>xsd</filetype>
<usage_type>resource</usage_type>
<checksum>AA9487CE</checksum>
</file>
<file>
<filename>hpxml_schematron/HPXMLvalidator.xml</filename>
<filetype>xml</filetype>
<usage_type>resource</usage_type>
<checksum>C24837D1</checksum>
</file>
<file>
<filename>test_validation.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>A673B23D</checksum>
</file>
<file>
<filename>hpxml_schema/HPXMLBaseElements.xsd</filename>
<filetype>xsd</filetype>
<usage_type>resource</usage_type>
<checksum>12DEE90E</checksum>
</file>
<file>
<filename>hpxml_schematron/EPvalidator.xml</filename>
<filetype>xml</filetype>
<usage_type>resource</usage_type>
<checksum>547D4876</checksum>
<checksum>78CF2A2D</checksum>
</file>
<file>
<filename>test_validation.rb</filename>
<filename>hpxml.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>A673B23D</checksum>
<usage_type>resource</usage_type>
<checksum>63E3E642</checksum>
</file>
<file>
<filename>hpxml.rb</filename>
<filename>output.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>AD09E7FF</checksum>
<checksum>A5AF01C9</checksum>
</file>
<file>
<filename>test_simcontrols.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>CF8094A4</checksum>
</file>
</files>
</measure>
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class HPXML < Object
WallTypeDoubleWoodStud = 'DoubleWoodStud'
WallTypeICF = 'InsulatedConcreteForms'
WallTypeLog = 'LogWall'
WallTypeSIP = 'StructurallyInsulatedPanel'
WallTypeSIP = 'StructuralInsulatedPanel'
WallTypeSteelStud = 'SteelFrame'
WallTypeStone = 'Stone'
WallTypeStrawBale = 'StrawBale'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@
<xs:element minOccurs="0" ref="AttachedToSpace"/>
<xs:element name="ExteriorAdjacentTo" type="AdjacentTo" minOccurs="0"/>
<xs:element minOccurs="0" name="InteriorAdjacentTo" type="AdjacentTo"/>
<xs:element name="FloorType" type="FloorType" minOccurs="0"/>
<xs:element minOccurs="0" name="FloorType" type="FloorType"/>
<xs:element minOccurs="0" name="FloorJoists" type="StudProperties"/>
<xs:element minOccurs="0" name="FloorTrusses" type="StudProperties"/>
<xs:element minOccurs="0" name="FloorCovering" type="FloorCovering"/>
Expand Down Expand Up @@ -5528,20 +5528,14 @@
</xs:complexType>
</xs:element>
<xs:element name="ConcreteMasonryUnit">
<xs:annotation>
<xs:documentation>Concrete Masonry Unit</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="extension"/>
</xs:sequence>
<xs:attribute name="dataSource" type="DataSource"/>
</xs:complexType>
</xs:element>
<xs:element name="StructurallyInsulatedPanel">
<xs:annotation>
<xs:documentation>Structurally Insulated Panel</xs:documentation>
</xs:annotation>
<xs:element name="StructuralInsulatedPanel">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="extension"/>
Expand All @@ -5550,9 +5544,6 @@
</xs:complexType>
</xs:element>
<xs:element name="InsulatedConcreteForms">
<xs:annotation>
<xs:documentation>Insulated Concrete Forms</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="extension"/>
Expand Down Expand Up @@ -5637,10 +5628,7 @@
<xs:attribute name="dataSource" type="DataSource"/>
</xs:complexType>
</xs:element>
<xs:element name="StructurallyInsulatedPanel">
<xs:annotation>
<xs:documentation>Structurally Insulated Panel</xs:documentation>
</xs:annotation>
<xs:element name="StructuralInsulatedPanel">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="extension"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@
<sch:assert role='ERROR' test='h:ExteriorAdjacentTo[text()="outside" or text()="attic - vented" or text()="attic - unvented" or text()="basement - conditioned" or text()="basement - unconditioned" or text()="crawlspace - vented" or text()="crawlspace - unvented" or text()="crawlspace - conditioned" or text()="garage" or text()="other housing unit" or text()="other heated space" or text()="other multifamily buffer space" or text()="other non-freezing space"] or not(h:ExteriorAdjacentTo)'>Expected ExteriorAdjacentTo to be 'outside' or 'attic - vented' or 'attic - unvented' or 'basement - conditioned' or 'basement - unconditioned' or 'crawlspace - vented' or 'crawlspace - unvented' or 'crawlspace - conditioned' or 'garage' or 'other housing unit' or 'other heated space' or 'other multifamily buffer space' or 'other non-freezing space'</sch:assert>
<sch:assert role='ERROR' test='count(h:InteriorAdjacentTo) = 1'>Expected 1 element(s) for xpath: InteriorAdjacentTo</sch:assert>
<sch:assert role='ERROR' test='h:InteriorAdjacentTo[text()="living space" or text()="attic - vented" or text()="attic - unvented" or text()="basement - conditioned" or text()="basement - unconditioned" or text()="crawlspace - vented" or text()="crawlspace - unvented" or text()="crawlspace - conditioned" or text()="garage"] or not(h:InteriorAdjacentTo)'>Expected InteriorAdjacentTo to be 'living space' or 'attic - vented' or 'attic - unvented' or 'basement - conditioned' or 'basement - unconditioned' or 'crawlspace - vented' or 'crawlspace - unvented' or 'crawlspace - conditioned' or 'garage'</sch:assert>
<sch:assert role='ERROR' test='count(h:WallType[h:WoodStud | h:DoubleWoodStud | h:ConcreteMasonryUnit | h:StructurallyInsulatedPanel | h:InsulatedConcreteForms | h:SteelFrame | h:SolidConcrete | h:StructuralBrick | h:StrawBale | h:Stone | h:LogWall | h:Adobe]) = 1'>Expected 1 element(s) for xpath: WallType[WoodStud | DoubleWoodStud | ConcreteMasonryUnit | StructurallyInsulatedPanel | InsulatedConcreteForms | SteelFrame | SolidConcrete | StructuralBrick | StrawBale | Stone | LogWall | Adobe]</sch:assert>
<sch:assert role='ERROR' test='count(h:WallType[h:WoodStud | h:DoubleWoodStud | h:ConcreteMasonryUnit | h:StructuralInsulatedPanel | h:InsulatedConcreteForms | h:SteelFrame | h:SolidConcrete | h:StructuralBrick | h:StrawBale | h:Stone | h:LogWall | h:Adobe]) = 1'>Expected 1 element(s) for xpath: WallType[WoodStud | DoubleWoodStud | ConcreteMasonryUnit | StructuralInsulatedPanel | InsulatedConcreteForms | SteelFrame | SolidConcrete | StructuralBrick | StrawBale | Stone | LogWall | Adobe]</sch:assert>
<sch:assert role='ERROR' test='count(h:Area) = 1'>Expected 1 element(s) for xpath: Area</sch:assert>
<sch:assert role='ERROR' test='count(h:Azimuth) + count(h:Orientation) &gt;= 0'>Expected 0 or more element(s) for xpath: Azimuth | Orientation</sch:assert>
<sch:assert role='ERROR' test='count(h:Siding) &lt;= 1'>Expected 0 or 1 element(s) for xpath: Siding</sch:assert>
Expand Down
26 changes: 22 additions & 4 deletions resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ class WT
end

class OutputMethods
def self.get_timestamps(msgpackData, hpxml, add_dst_column = false, add_utc_column = false, use_dview_format = false)
def self.get_timestamps(msgpackData, hpxml, use_timestamp_start_convention, add_dst_column = false, add_utc_column = false,
use_dview_format = false, timeseries_frequency = nil)
return if msgpackData.nil?

if msgpackData.keys.include? 'MeterData'
Expand All @@ -162,12 +163,29 @@ def self.get_timestamps(msgpackData, hpxml, add_dst_column = false, add_utc_colu
timestamps = []
timestamps_dst = [] if add_dst_column || use_dview_format
timestamps_utc = [] if add_utc_column
year = hpxml.header.sim_calendar_year.to_s
year = hpxml.header.sim_calendar_year
ep_timestamps.each do |ep_timestamp|
month_day, hour_minute = ep_timestamp.split(' ')
month, day = month_day.split('/')
hour, minute, _ = hour_minute.split(':')
month, day = month_day.split('/').map(&:to_i)
hour, minute, _ = hour_minute.split(':').map(&:to_i)

# Convert from EnergyPlus default (end-of-timestep) to start-of-timestep convention
if use_timestamp_start_convention
if timeseries_frequency == 'timestep'
ts_offset = hpxml.header.timestep * 60 # seconds
elsif timeseries_frequency == 'hourly'
ts_offset = 60 * 60 # seconds
elsif timeseries_frequency == 'daily'
ts_offset = 60 * 60 * 24 # seconds
elsif timeseries_frequency == 'monthly'
ts_offset = Constants.NumDaysInMonths(year)[month - 1] * 60 * 60 * 24 # seconds
else
fail 'Unexpected timeseries_frequency/'
end
end

ts = Time.utc(year, month, day, hour, minute)
ts -= ts_offset unless ts_offset.nil?

timestamps << ts.iso8601.delete('Z')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ def test_run_period_1month
model, _hpxml = _test_measure(args_hash)

begin_month, begin_day, end_month, end_day = get_run_period_month_and_days(model)
assert_equal(1, begin_month)
assert_equal(2, begin_month)
assert_equal(1, begin_day)
assert_equal(1, end_month)
assert_equal(31, end_day)
assert_equal(2, end_month)
assert_equal(28, end_day)
end

def test_timestep_1hour
Expand Down
34 changes: 17 additions & 17 deletions resources/hpxml-measures/ReportSimulationOutput/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
arg.setDefaultValue(false)
args << arg

timestamp_chs = OpenStudio::StringVector.new
timestamp_chs << 'start'
timestamp_chs << 'end'
arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('timeseries_timestamp_convention', timestamp_chs, false)
arg.setDisplayName('Generate Timeseries Output: Timestamp Convention')
arg.setDescription("Determines whether timeseries timestamps use the start-of-timestep or end-of-timestep convention. Doesn't apply if the output format is 'csv_dview'.")
arg.setDefaultValue('start')
args << arg

arg = OpenStudio::Measure::OSArgument::makeBoolArgument('add_timeseries_dst_column', false)
arg.setDisplayName('Generate Timeseries Output: Add TimeDST Column')
arg.setDescription('Optionally add, in addition to the default local standard Time column, a local clock TimeDST column. Requires that daylight saving time is enabled.')
Expand Down Expand Up @@ -229,8 +238,7 @@ def energyPlusOutputRequests(runner, user_arguments)
has_heating = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_heating').get
has_cooling = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_cooling').get

timeseries_frequency = runner.getOptionalStringArgumentValue('timeseries_frequency', user_arguments)
timeseries_frequency = timeseries_frequency.is_initialized ? timeseries_frequency.get : 'none'
timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
if timeseries_frequency != 'none'
include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
Expand Down Expand Up @@ -454,8 +462,7 @@ def run(runner, user_arguments)
output_format = 'csv'
use_dview_format = true
end
timeseries_frequency = runner.getOptionalStringArgumentValue('timeseries_frequency', user_arguments)
timeseries_frequency = timeseries_frequency.is_initialized ? timeseries_frequency.get : 'none'
timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
if timeseries_frequency != 'none'
include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
Expand All @@ -470,6 +477,7 @@ def run(runner, user_arguments)
include_timeseries_zone_temperatures = runner.getOptionalBoolArgumentValue('include_timeseries_zone_temperatures', user_arguments)
include_timeseries_airflows = runner.getOptionalBoolArgumentValue('include_timeseries_airflows', user_arguments)
include_timeseries_weather = runner.getOptionalBoolArgumentValue('include_timeseries_weather', user_arguments)
use_timestamp_start_convention = (runner.getStringArgumentValue('timeseries_timestamp_convention', user_arguments) == 'start')
add_timeseries_dst_column = runner.getOptionalBoolArgumentValue('add_timeseries_dst_column', user_arguments)
add_timeseries_utc_column = runner.getOptionalBoolArgumentValue('add_timeseries_utc_column', user_arguments)
user_output_variables = runner.getOptionalStringArgumentValue('user_output_variables', user_arguments)
Expand Down Expand Up @@ -532,7 +540,8 @@ def run(runner, user_arguments)
if timeseries_frequency != 'none'
add_dst_column = (add_timeseries_dst_column.is_initialized ? add_timeseries_dst_column.get : false)
add_utc_column = (add_timeseries_utc_column.is_initialized ? add_timeseries_utc_column.get : false)
@timestamps, timestamps_dst, timestamps_utc = OutputMethods.get_timestamps(@msgpackDataTimeseries, @hpxml, add_dst_column, add_utc_column, use_dview_format)
@timestamps, timestamps_dst, timestamps_utc = OutputMethods.get_timestamps(@msgpackDataTimeseries, @hpxml, use_timestamp_start_convention,
add_dst_column, add_utc_column, use_dview_format, timeseries_frequency)
end

# Retrieve outputs
Expand Down Expand Up @@ -1621,23 +1630,14 @@ def report_timeseries_output_results(runner, outputs, output_format,
end

# Initial output data w/ Time column(s)
data = ['Time', nil]
@timestamps.each do |timestamp|
data << timestamp
end
data = ['Time', nil] + @timestamps
if add_dst_column
timestamps2 = [['TimeDST', nil]]
timestamps_dst.each do |timestamp|
timestamps2[0] << timestamp
end
timestamps2 = [['TimeDST', nil] + timestamps_dst]
else
timestamps2 = []
end
if add_utc_column
timestamps3 = [['TimeUTC', nil]]
timestamps_utc.each do |timestamp|
timestamps3[0] << timestamp
end
timestamps3 = [['TimeUTC', nil] + timestamps_utc]
else
timestamps3 = []
end
Expand Down

0 comments on commit 0ae1158

Please sign in to comment.