Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre peak check #1332

Draft
wants to merge 94 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
172879c
Rename ResstockArguments to ResStockArgumentsPreHPXML.
joseph-robertson May 13, 2022
fa408c7
Update measure name in other measures and lookup.
joseph-robertson May 13, 2022
44347c3
Stub new ResStockArgumentsPostHPXML measure.
joseph-robertson May 13, 2022
771042c
Update meta measures for new measure.
joseph-robertson May 13, 2022
2abcc64
Get meta measures working properly.
joseph-robertson May 13, 2022
1587e5b
Update measure descriptions.
joseph-robertson May 13, 2022
7bdf4da
More description updates.
joseph-robertson May 13, 2022
e111940
Merge branch 'develop' into resstock-args-refactor
joseph-robertson May 13, 2022
6fad137
Rename pre hpxml back to original.
joseph-robertson May 13, 2022
fd288ae
Revert lookup.
joseph-robertson May 13, 2022
06133ea
Merge branch 'develop' into resstock-args-refactor
joseph-robertson May 17, 2022
87e876b
Measure updates.
joseph-robertson May 17, 2022
957b9c9
Temp code in building existing model.
joseph-robertson May 17, 2022
3a5effb
Remove project folders before each test.
joseph-robertson May 17, 2022
be0e390
Squashed 'resources/hpxml-measures/' changes from c015c17d0ee..cdaa49…
joseph-robertson May 19, 2022
a8bfe43
Merge commit 'be0e390519975d5028881cfb584b5c89bef9f497' into resstock…
joseph-robertson May 19, 2022
94c5b04
Ignore new debug argument for resstock arguments.
joseph-robertson May 19, 2022
e6736f6
Merge branch 'develop' into resstock-args-refactor
joseph-robertson May 19, 2022
5c23cf2
Request setpoint output vars.
joseph-robertson May 20, 2022
53f3fc0
Latest results.
May 21, 2022
a8fc8d3
Merge branch 'develop' into resstock-args-refactor
joseph-robertson Jun 6, 2022
bfa8478
Merge branch 'develop' into resstock-args-refactor
joseph-robertson Jul 8, 2022
76ef1b6
Latest results.
Jul 8, 2022
d2d0ceb
Merge branch 'develop' into resstock-args-refactor
joseph-robertson Nov 3, 2022
55b9fa5
Clean up top level measures.
joseph-robertson Nov 3, 2022
c7c7948
Latest results.
Nov 4, 2022
4f7106d
Update changelog.
joseph-robertson Nov 4, 2022
87279c6
Update docs.
joseph-robertson Nov 4, 2022
2dac598
Revert output vars request in yml.
joseph-robertson Nov 4, 2022
ecd366d
Latest results.
Nov 4, 2022
abae054
Merge branch 'develop' into resstock-args-refactor
joseph-robertson Nov 14, 2022
b68c82f
Merge branch 'develop' into resstock-args-refactor
joseph-robertson Nov 16, 2022
5d68279
Initial measure draft
rajeee Jun 17, 2024
f407433
Test calling measure through upgrade
rajeee Jun 17, 2024
40142ea
Pass building info
rajeee Jun 18, 2024
23203d7
Commit flake8 file
rajeee Jun 18, 2024
d078a6e
demand response
Jun 20, 2024
758bc6f
on-peak hour
Jun 20, 2024
4aeb5d1
Add unit test
rajeee Jun 25, 2024
0cad8f9
adjust on-peak duration
Jul 24, 2024
f4dcde1
options lookup
Jul 24, 2024
87d7f43
unit test
Jul 26, 2024
8932ce8
unit test
Jul 26, 2024
e1df54a
Improve data structure
rajeee Aug 2, 2024
f4cfaa8
unit test
Aug 6, 2024
9441a9f
unit test
Aug 6, 2024
3e4a246
Update test files
rajeee Aug 13, 2024
3e0fe10
Merge branch 'load_flexibility' of https://github.com/NREL/resstock i…
rajeee Aug 13, 2024
fbad4bd
Some refactoring
rajeee Aug 14, 2024
d552b60
Merge branch 'develop' into load_flexibility
rajeee Aug 14, 2024
8401818
Some refactoring
rajeee Aug 16, 2024
1c724c0
Some missing files
rajeee Aug 16, 2024
1ae7ef1
unit test
Aug 31, 2024
c189cfe
unit test
Sep 5, 2024
6bd3241
unit test
Sep 5, 2024
659198f
revert testing upgrades yaml changes
rajeee Oct 8, 2024
32d990f
Make the test files run as script
rajeee Oct 8, 2024
b9670d6
Merge branch 'develop' into load_flexibility
rajeee Oct 8, 2024
56895df
Add python unit tests
rajeee Oct 8, 2024
c034212
Add python unit tests fix
rajeee Oct 8, 2024
faa4ff9
Run unit tests through openstudio directly
rajeee Oct 9, 2024
331437d
Changes to make it work with latest OS-HPXML
rajeee Oct 14, 2024
bd316de
Merge branch 'develop' into resstock-args-refactor
rajeee Oct 14, 2024
18f62ab
Cleanup merge conflicts
rajeee Oct 14, 2024
dae2310
Reimplment calling ResStockArgumentsPostHPXML
rajeee Oct 14, 2024
c454026
Update measures
rajeee Oct 15, 2024
e7b642e
Merge branch 'ci_fix' into resstock-args-refactor
rajeee Oct 15, 2024
17e85f5
Update to use runner method
rajeee Oct 15, 2024
7db1464
Merge branch 'resstock-args-refactor' into load_flexibility
rajeee Oct 15, 2024
a0c4ce7
Move create schedule to PostHPXML measure
rajeee Oct 15, 2024
6337168
Rename resource file
rajeee Oct 15, 2024
95f5936
Merge branch 'develop' into resstock-args-refactor
rajeee Oct 16, 2024
c010da9
Remove old CHANGELOG [skip ci]
rajeee Oct 29, 2024
1d0b67d
Merge branch 'develop' into resstock-args-refactor
rajeee Oct 29, 2024
05cdc4c
Use python 3.11 for CI
rajeee Oct 30, 2024
121b23f
Modify setpoints
rajeee Nov 4, 2024
cb2047c
More updates
rajeee Nov 5, 2024
8d088c4
Call ResStockArgumentsPostHPXML properly
rajeee Nov 5, 2024
e3e3a9e
Merge branch 'resstock-args-refactor' into load_flexibility
rajeee Nov 5, 2024
67ba473
Commit options lookup update and yaml changes
rajeee Nov 5, 2024
d842b56
Revert workflow generator version update
rajeee Nov 5, 2024
abe9c0b
Revert HPXML changes
rajeee Nov 5, 2024
6345b33
Remove standalond flexbility measure
rajeee Nov 5, 2024
8989216
Remove all changes from hpxml-measures
rajeee Nov 5, 2024
f80bcb0
Remove all changes from hpxml-measures
rajeee Nov 5, 2024
2cc34bb
Remove byebug
rajeee Nov 5, 2024
b028c9e
handle inverted setpoints
rajeee Nov 18, 2024
a6228ae
BuildExistingModel Fix
rajeee Nov 18, 2024
93131ea
get test_hvac_load_flexibility.rb run
Nov 20, 2024
289527f
Merge branch 'develop' into load_flexibility
rajeee Nov 25, 2024
8349813
pre_peak_sensitivity_analysis
rajeee Dec 16, 2024
a136bbe
pre_peak_sensitivity_analysis
rajeee Dec 16, 2024
9b8e54b
Add AK and HI peak hours
rajeee Dec 16, 2024
3d1bff0
redo_prepeak_sensitivity
rajeee Dec 16, 2024
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
11 changes: 11 additions & 0 deletions docs/read_the_docs/source/basic_tutorial/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ The BuildExistingModel and ApplyUpgrade meta measures call the following model m
1 ResStockArguments Model No ResStock
2 BuildResidentialHPXML Model No OS-HPXML
3 BuildResidentialScheduleFile Model No OS-HPXML
4 ResStockArgumentsPostHPXML Model No ResStock
===== ============================= ================== ========= ============= ==========================

.. _model-measures:
Expand Down Expand Up @@ -117,6 +118,16 @@ They contribute to the generation of the model.
:start-after: <modeler_description>
:end-before: <

**ResStockArgumentsPostHPXML**

.. include:: ../../../../measures/ResStockArgumentsPostHPXML/measure.xml
:start-after: <description>
:end-before: <

.. include:: ../../../../measures/ResStockArgumentsPostHPXML/measure.xml
:start-after: <modeler_description>
:end-before: <

.. _tutorial-apply-upgrade:

**ApplyUpgrade**
Expand Down
16 changes: 16 additions & 0 deletions docs/read_the_docs/source/changelog/changelog_dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,19 @@ Development Changelog

Description:
The purpose of this PR is to set a value in ResStockArguments for apartment units based on the type/size of MF building and where the unit is located (lower, middle, or upper story).

.. change::
:tags: workflow, feature
:pullreq: 929

**Date**: 2024-10-14

Title:
New ResStockArgumentsPostHPXML measure

Description:
This measure is added to the workflow to post-process the output of the BuildResidentialHPXML and BuildResidentialScheduleFile measures.

Assignees: Joe Robertson, Rajendra Adhikari

GitHub: `pull request 929 <https://github.com/NREL/resstock/pull/929>`_
14 changes: 12 additions & 2 deletions measures/ApplyUpgrade/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -519,11 +519,21 @@ def run(model, runner, user_arguments)
register_logs(runner, new_runner)
return false
end
measures['ResStockArgumentsPostHPXML'] = [{}] if !measures.keys.include?('ResStockArgumentsPostHPXML')
measures['ResStockArgumentsPostHPXML'][0]['hpxml_path'] = hpxml_path
measures['ResStockArgumentsPostHPXML'][0]['output_csv_path'] = File.expand_path('../schedules.csv')
measures['ResStockArgumentsPostHPXML'][0]['building_id'] = values['building_id']
measures_hash = { 'ResStockArgumentsPostHPXML' => measures['ResStockArgumentsPostHPXML'] }
if not apply_measures(measures_dir, measures_hash, new_runner, model, true, 'OpenStudio::Measure::ModelMeasure', nil)
register_logs(runner, new_runner)
return false
end

# Specify measures to run
measures_to_apply_hash = { measures_dir => {} }

upgrade_measures = measures.keys - ['ResStockArguments', 'BuildResidentialHPXML', 'BuildResidentialScheduleFile']
upgrade_measures = measures.keys - ['ResStockArguments', 'BuildResidentialHPXML', 'BuildResidentialScheduleFile',
'ResStockArgumentsPostHPXML']
upgrade_measures.each do |upgrade_measure|
measures_to_apply_hash[measures_dir][upgrade_measure] = measures[upgrade_measure]
end
Expand All @@ -537,14 +547,14 @@ def run(model, runner, user_arguments)
register_logs(runner, new_runner)
return false
end

# Copy upgraded.xml to home.xml for downstream HPXMLtoOpenStudio
# This will overwrite home.xml from BuildExistingModel
# We need upgraded.xml (and not just home.xml) for UpgradeCosts
in_path = File.expand_path('../home.xml')
FileUtils.cp(hpxml_path, in_path)

register_logs(runner, resstock_arguments_runner)
register_logs(runner, new_runner)

return true
end
Expand Down
11 changes: 11 additions & 0 deletions measures/BuildExistingModel/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,16 @@ def run(model, runner, user_arguments)
end
end

measures['ResStockArgumentsPostHPXML'] = [{}] if !measures.keys.include?('ResStockArgumentsPostHPXML')
measures['ResStockArgumentsPostHPXML'][0]['hpxml_path'] = hpxml_path
measures['ResStockArgumentsPostHPXML'][0]['output_csv_path'] = File.expand_path('../schedules.csv')
measures['ResStockArgumentsPostHPXML'][0]['building_id'] = args[:building_id]
measures_hash = { 'ResStockArgumentsPostHPXML' => measures['ResStockArgumentsPostHPXML'] }
if not apply_measures(measures_dir, measures_hash, new_runner, model, true, 'OpenStudio::Measure::ModelMeasure', nil)
register_logs(runner, new_runner)
return false
end

# Copy existing.xml to home.xml for downstream HPXMLtoOpenStudio
# We need existing.xml (and not just home.xml) for UpgradeCosts
in_path = File.expand_path('../home.xml')
Expand Down Expand Up @@ -806,6 +816,7 @@ def run(model, runner, user_arguments)
end

register_logs(runner, resstock_arguments_runner)
register_logs(runner, new_runner)

return true
end
Expand Down
2 changes: 1 addition & 1 deletion measures/ResStockArguments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
## Description
Measure that pre-processes the arguments passed to the BuildResidentialHPXML and BuildResidentialScheduleFile measures.

Passes in all arguments from the options lookup, processes them, and then registers values to the runner to be used by other measures.
Passes in all ResStockArguments arguments from the options lookup, processes them, and then registers values to the runner to be used by other measures.

## Arguments

Expand Down
2 changes: 1 addition & 1 deletion measures/ResStockArguments/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def description

# human readable description of modeling approach
def modeler_description
return 'Passes in all arguments from the options lookup, processes them, and then registers values to the runner to be used by other measures.'
return 'Passes in all ResStockArguments arguments from the options lookup, processes them, and then registers values to the runner to be used by other measures.'
end

# define the arguments that the user will input
Expand Down
184 changes: 184 additions & 0 deletions measures/ResStockArgumentsPostHPXML/measure.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# frozen_string_literal: true

# see the URL below for information on how to write OpenStudio measures
# http://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/

require_relative 'resources/hvac_flexibility/detailed_schedule_generator'
require_relative 'resources/hvac_flexibility/setpoint_modifier'

# start the measure
class ResStockArgumentsPostHPXML < OpenStudio::Measure::ModelMeasure
# human readable name
def name
# Measure name should be the title case of the class name.
return 'ResStock Arguments Post-HPXML'
end

# human readable description
def description
return 'Measure that post-processes the output of the BuildResidentialHPXML and BuildResidentialScheduleFile measures.'
end

# human readable description of modeling approach
def modeler_description
return 'Passes in all ResStockArgumentsPostHPXML arguments from the options lookup, processes them, and then modifies output of other measures.'
end

# define the arguments that the user will input
def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
args = OpenStudio::Measure::OSArgumentVector.new

arg = OpenStudio::Measure::OSArgument.makeStringArgument('hpxml_path', false)
arg.setDisplayName('HPXML File Path')
arg.setDescription('Absolute/relative path of the HPXML file.')
args << arg

# Add args for flexibility inputs. Use hours format for the duration and minutes for the random offset. Offsets are degree F.
arg = OpenStudio::Measure::OSArgument.makeDoubleArgument('loadflex_peak_duration_hours', false)
arg.setDisplayName('Load Flexibility: Peak Duration (hours)')
arg.setDescription('Duration of the peak period in hours.')
arg.setDefaultValue(0)
args << arg

arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('loadflex_peak_offset', false)
arg.setDisplayName('Load Flexibility: Peak Offset (deg F)')
arg.setDescription('Offset of the peak period in degrees Fahrenheit.')
arg.setDefaultValue(0)
args << arg

arg = OpenStudio::Measure::OSArgument.makeDoubleArgument('loadflex_pre_peak_duration_hours', false)
arg.setDisplayName('Load Flexibility: Pre-Peak Duration (hours)')
arg.setDescription('Duration of the pre-peak period in hours.')
arg.setDefaultValue(0)
args << arg

arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('loadflex_pre_peak_offset', false)
arg.setDisplayName('Load Flexibility: Pre-Peak Offset (deg F)')
arg.setDescription('Offset of the pre-peak period in degrees Fahrenheit.')
arg.setDefaultValue(0)
args << arg

arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('loadflex_random_shift_minutes', false)
arg.setDisplayName('Load Flexibility: Random Shift (minutes)')
arg.setDescription('Number of minutes to randomly shift the peak period. If minutes less than timestep, will be assumed to be 0.')
arg.setDefaultValue(0)
args << arg

arg = OpenStudio::Measure::OSArgument::makeStringArgument('output_csv_path', false)
arg.setDisplayName('Schedules: Output CSV Path')
arg.setDescription('Absolute/relative path of the csv file containing user-specified occupancy schedules. Relative paths are relative to the HPXML output path.')
args << arg

arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('building_id', false)
arg.setDisplayName('Building Unit ID')
arg.setDescription('The building unit number (between 1 and the number of samples).')
args << arg

return args
end

# define what happens when the measure is run
def run(model, runner, user_arguments)
super(model, runner, user_arguments)

# use the built-in error checking
if !runner.validateUserArguments(arguments(model), user_arguments)
return false
end

# assign the user inputs to variables
args = runner.getArgumentValues(arguments(model), user_arguments)
if skip_load_flexibility?(args)
runner.registerInfo('Skipping ResStockArgumentsPostHPXML since load flexibility inputs are 0.')
return true
end

hpxml_path = args[:hpxml_path]
unless (Pathname.new hpxml_path).absolute?
hpxml_path = File.expand_path(File.join(File.dirname(__FILE__), hpxml_path))
end
unless File.exist?(hpxml_path) && hpxml_path.downcase.end_with?('.xml')
fail "'#{hpxml_path}' does not exist or is not an .xml file."
end

hpxml = HPXML.new(hpxml_path: hpxml_path)

# Parse the HPXML document
doc = XMLHelper.parse_file(hpxml_path)
hpxml_doc = XMLHelper.get_element(doc, '/HPXML')
doc_buildings = XMLHelper.get_elements(hpxml_doc, 'Building')

# Process each building
doc_buildings.each_with_index do |building, index|
schedule = create_schedule(hpxml, hpxml_path, runner, index)
modified_schedule = modify_schedule(hpxml, index, args, runner, schedule)
schedules_filepath = write_schedule(modified_schedule, args[:output_csv_path], index)
update_hpxml_schedule_filepath(building, schedules_filepath)
end

# Write out the modified hpxml
XMLHelper.write_file(doc, hpxml_path)
runner.registerInfo("Wrote file: #{hpxml_path} with modified schedules.")
true
end

def skip_load_flexibility?(args)
args[:loadflex_peak_duration_hours] == 0 && args[:loadflex_pre_peak_duration_hours] == 0
end

def create_schedule(hpxml, hpxml_path, runner, building_index)
generator = HVACScheduleGenerator.new(hpxml, hpxml_path, runner, building_index)
generator.get_heating_cooling_setpoint_schedule
end

def modify_schedule(hpxml, building_index, args, runner, schedule)
minutes_per_step = hpxml.header.timestep
hpxml_bldg = hpxml.buildings[building_index]
building_id = (args[:building_id] or 0).to_i
state = hpxml_bldg.state_code
sim_year = hpxml.header.sim_calendar_year
epw_path = Location.get_epw_path(hpxml_bldg, args[:hpxml_path])
weather = WeatherFile.new(epw_path: epw_path, runner: runner, hpxml: hpxml)
schedule_modifier = HVACScheduleModifier.new(state: state,
sim_year: sim_year,
weather: weather,
epw_path: epw_path,
minutes_per_step: minutes_per_step,
runner: runner)
flexibility_inputs = get_flexibility_inputs(args, minutes_per_step, building_id)
schedule_modifier.modify_setpoints(schedule, flexibility_inputs)
end

def get_flexibility_inputs(args, minutes_per_step, building_id)
srand(building_id)
max_random_shift_steps = (args[:loadflex_random_shift_minutes] / minutes_per_step).to_i
random_shift_steps = rand(-max_random_shift_steps..max_random_shift_steps)
FlexibilityInputs.new(
peak_duration_steps: (args[:loadflex_peak_duration_hours] * 60 / minutes_per_step).to_i,
peak_offset: args[:loadflex_peak_offset],
pre_peak_duration_steps: (args[:loadflex_pre_peak_duration_hours] * 60 / minutes_per_step).to_i,
pre_peak_offset: args[:loadflex_pre_peak_offset],
random_shift_steps: random_shift_steps
)
end

def write_schedule(schedule, output_csv_path, building_index)
schedules_filepath = File.join(File.dirname(output_csv_path), "detailed_schedules_#{building_index + 1}.csv")
CSV.open(schedules_filepath, 'w') do |csv|
csv << schedule.keys
schedule.values.transpose.each do |row|
csv << row.map { |x| '%.3g' % x }
end
end
return schedules_filepath
end

def update_hpxml_schedule_filepath(building, new_schedule_filepath)
building_extension = XMLHelper.create_elements_as_needed(building, ['BuildingDetails', 'BuildingSummary', 'extension'])
existing_schedules_filepaths = XMLHelper.get_values(building_extension, 'SchedulesFilePath', :string)
XMLHelper.add_element(building_extension, 'SchedulesFilePath', new_schedule_filepath, :string) unless existing_schedules_filepaths.include?(new_schedule_filepath)
end
end

# register the measure to be used by the application
ResStockArgumentsPostHPXML.new.registerWithApplication
56 changes: 56 additions & 0 deletions measures/ResStockArgumentsPostHPXML/measure.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0"?>
<measure>
<schema_version>3.0</schema_version>
<name>res_stock_arguments_post_hpxml</name>
<uid>db102ce5-ac96-4ef9-90d3-abbe53478716</uid>
<version_id>e9a3773b-66b5-48a6-95e5-4ce42262a640</version_id>
<version_modified>20221103T232039Z</version_modified>
<xml_checksum>2C38F48B</xml_checksum>
<class_name>ResStockArgumentsPostHPXML</class_name>
<display_name>ResStock Arguments Post-HPXML</display_name>
<description>Measure that post-processes the output of the BuildResidentialHPXML and BuildResidentialScheduleFile measures.</description>
<modeler_description>Passes in all ResStockArgumentsPostHPXML arguments from the options lookup, processes them, and then modifies output of other measures.</modeler_description>
<arguments>
<argument>
<name>hpxml_path</name>
<display_name>HPXML File Path</display_name>
<description>Absolute/relative path of the HPXML file.</description>
<type>String</type>
<required>false</required>
<model_dependent>false</model_dependent>
</argument>
<argument>
<name>output_csv_path</name>
<display_name>Schedules: Output CSV Path</display_name>
<description>Absolute/relative path of the csv file containing user-specified occupancy schedules. Relative paths are relative to the HPXML output path.</description>
<type>String</type>
<required>false</required>
<model_dependent>false</model_dependent>
</argument>
</arguments>
<outputs />
<provenances />
<tags>
<tag>Whole Building.Space Types</tag>
</tags>
<attributes>
<attribute>
<name>Measure Type</name>
<value>ModelMeasure</value>
<datatype>string</datatype>
</attribute>
</attributes>
<files>
<file>
<version>
<software_program>OpenStudio</software_program>
<identifier>3.3.0</identifier>
<min_compatible>3.3.0</min_compatible>
</version>
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>5A9AF6DF</checksum>
</file>
</files>
</measure>
Loading