From ea141e2e29b6e950a73c65b370513f0057703a84 Mon Sep 17 00:00:00 2001 From: Tobias Shapinsky Date: Thu, 20 Jun 2024 13:04:02 -0600 Subject: [PATCH] Update to openstudio 3.8, e+ 24.1 and pyfmi 2.11 (#491) * update to openstudio 3.8, e+ 24.1 and pyfmi 2.11 * clean up RunPeriod and Timestep substitution * update refrig case model * point worker image to main branch of dependencies repo * point dockerfile to released alfalfa dependencies --- .pre-commit-config.yaml | 2 +- alfalfa_worker/Dockerfile | 7 +- alfalfa_worker/jobs/openstudio/create_run.py | 2 +- .../alfalfa_prepare_idf/measure.rb} | 59 +- .../measures/alfalfa_prepare_idf/measure.xml | 44 ++ .../alfalfa_python_environment/measure.rb | 1 + .../alfalfa_python_environment/measure.xml | 13 +- .../alfalfa_setpoint_control/measure.xml | 21 +- .../measures/alfalfa_site_sensors/measure.xml | 10 +- .../measures/alfalfa_zone_sensors/measure.xml | 10 +- .../measures/export_bcvtb/measure.xml | 128 ++-- .../expose_time_variables/measure.xml | 139 ++-- .../workflow/measures/haystack/measure.xml | 167 ++--- .../openstudio-alfalfa-gem/.gitignore | 29 - .../workflow/openstudio-alfalfa-gem/Gemfile | 44 -- .../workflow/openstudio-alfalfa-gem/README.md | 37 - .../workflow/openstudio-alfalfa-gem/Rakefile | 40 -- .../doc_templates/LICENSE.md | 27 - .../doc_templates/README.md.erb | 42 -- .../doc_templates/copyright_erb.txt | 36 - .../doc_templates/copyright_js.txt | 4 - .../doc_templates/copyright_ruby.txt | 34 - .../lib/measures/haystack/measure.rb | 630 ------------------ .../lib/measures/haystack/measure.xml | 83 --- .../lib/openstudio-alfalfa.rb | 1 - .../lib/openstudio/alfalfa.rb | 51 -- .../lib/openstudio/alfalfa/tagger.rb | 232 ------- .../lib/openstudio/alfalfa/version.rb | 40 -- .../openstudio-alfalfa.gemspec | 56 -- .../spec/spec_helper.rb | 49 -- .../workflow/openstudio-alfalfa-gem/test.rb | 40 -- .../jobs/openstudio/lib/workflow/workflow.osw | 7 + alfalfa_worker/jobs/openstudio/step_run.py | 90 +-- alfalfa_worker/lib/testcase.py | 2 +- .../integration/models/refrig_case_osw/in.idf | 8 +- .../measures/alfalfa_vars/measure.xml | 8 +- .../measures/prep_idf/measure.rb | 1 + .../measures/prep_idf/measure.xml | 12 +- .../measures/replace_idf/measure.rb | 1 + .../measures/replace_idf/measure.xml | 14 +- .../measures/python_ems/measure.rb | 36 +- .../measures/python_ems/measure.xml | 4 +- 42 files changed, 415 insertions(+), 1846 deletions(-) rename alfalfa_worker/jobs/openstudio/lib/workflow/{openstudio-alfalfa-gem/spec/tests/alfalfa_spec.rb => measures/alfalfa_prepare_idf/measure.rb} (61%) create mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.xml delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/.gitignore delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Gemfile delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/README.md delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Rakefile delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/LICENSE.md delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/README.md.erb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_erb.txt delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_js.txt delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_ruby.txt delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.xml delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio-alfalfa.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/tagger.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/version.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/openstudio-alfalfa.gemspec delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/spec_helper.rb delete mode 100644 alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/test.rb diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3bad2db7..4149a7c9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,7 +52,7 @@ repos: "--ignore-init-module-imports" ] - repo: https://github.com/pycqa/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 args: ["--ignore=E501,E402,W503,W504,E731,F401"] diff --git a/alfalfa_worker/Dockerfile b/alfalfa_worker/Dockerfile index 8af55cd1..dfecf084 100644 --- a/alfalfa_worker/Dockerfile +++ b/alfalfa_worker/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/nrel/alfalfa-dependencies:2.0.0 AS base +FROM ghcr.io/nrel/alfalfa-dependencies:3.0.0 AS base USER root @@ -11,6 +11,7 @@ ENV DEBIAN_FRONTEND noninteractive # Install poetry RUN pip3 install poetry==1.8.3 +RUN poetry config virtualenvs.options.system-site-packages true # Copy and install poetry-based dependencies COPY pyproject.toml /alfalfa @@ -23,9 +24,7 @@ RUN poetry install --only main ENV PYTHONPATH="/alfalfa:${PYTHONPATH}" COPY ./alfalfa_worker /alfalfa/alfalfa_worker -RUN cd alfalfa_worker/jobs/openstudio/lib/alfalfa-lib-gem \ - && gem build alfalfa-lib-gem.gemspec \ - && gem install ./alfalfa-lib-0.0.0.gem + COPY ./deploy /alfalfa/deploy COPY ./deploy/wait-for-it.sh /usr/local/wait-for-it.sh diff --git a/alfalfa_worker/jobs/openstudio/create_run.py b/alfalfa_worker/jobs/openstudio/create_run.py index 7bf955d8..2fd96cae 100644 --- a/alfalfa_worker/jobs/openstudio/create_run.py +++ b/alfalfa_worker/jobs/openstudio/create_run.py @@ -44,7 +44,7 @@ def exec(self): check_output(['openstudio', str(lib_dir / 'merge_osws.rb'), str(default_workflow_path), str(submitted_osw_path)]) # run workflow - check_output(['openstudio', '--gem_path', '/var/lib/gems/2.7.0', 'run', '-m', '-w', str(submitted_osw_path)]) + check_output(['openstudio', '-I', '/alfalfa/alfalfa_worker/jobs/openstudio/lib/alfalfa-lib-gem/lib', 'run', '-m', '-w', str(submitted_osw_path)]) self.logger.info('Loading Building Metadata') metadata_json_path = submitted_workflow_path / 'reports' / 'alfalfa_metadata_report_metadata.json' diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/tests/alfalfa_spec.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.rb similarity index 61% rename from alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/tests/alfalfa_spec.rb rename to alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.rb index 7f563185..57f38731 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/tests/alfalfa_spec.rb +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.rb @@ -1,5 +1,5 @@ # ******************************************************************************* -# OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. +# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -33,20 +33,57 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ******************************************************************************* -require_relative '../spec_helper' +# start the measure +class AlfalfaPrepareIDF < OpenStudio::Ruleset::WorkspaceUserScript -RSpec.describe OpenStudio::Alfalfa do - it 'has a version number' do - expect(OpenStudio::Alfalfa::VERSION).not_to be nil + # human readable name + def name + return 'Alfalfa Prepare IDF' end - it 'has a measures directory' do - instance = OpenStudio::Alfalfa::Alfalfa.new - expect(File.exist?(instance.measures_dir)).to be true + # human readable description + def description + return 'Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution' end - it 'exists' do - x = OpenStudio::Alfalfa::Tagger.new - expect(x.class.to_s == 'OpenStudio::Alfalfa::Tagger').to be true + # human readable description of modeling approach + def modeler_description + return 'Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution' end + + # define the arguments that the user will input + def arguments(workspace) + args = OpenStudio::Ruleset::OSArgumentVector.new + return args + end + + # define what happens when the measure is run + def run(ws, runner, user_args) + + # call the parent class method + super(ws, runner, user_args) + + # use the built-in error checking + return false unless runner.validateUserArguments( + arguments(ws), + user_args + ) + + timestep_objs = ws.getObjectsByType('Timestep'.to_IddObjectType) + runperiod_objs = ws.getObjectsByType('RunPeriod'.to_IddObjectType) + + timestep_objs.each do |timestep| + timestep.remove() + end + + runperiod_objs.each do |runperiod| + runperiod.remove() + end + + return true + end + end + +# register the measure to be used by the application +AlfalfaPrepareIDF.new.registerWithApplication diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.xml new file mode 100644 index 00000000..92cbe0c5 --- /dev/null +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_prepare_idf/measure.xml @@ -0,0 +1,44 @@ + + + 3.1 + alfalfa_prepare_idf + 16125428-fcf9-4986-9d9b-3644225a2b6d + ed0d5b56-97c3-4dde-bf4a-937d382043fe + 2024-05-10T15:00:59Z + 7A4781A5 + AlfalfaPrepareIDF + Alfalfa Prepare IDF + Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution + Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution + + + + + Tool.Alfalfa + + + + Measure Type + EnergyPlusMeasure + string + + + Intended Software Tool + OpenStudio Application + string + + + + + + OpenStudio + 2.3.0 + 2.3.0 + + measure.rb + rb + script + 0267B29F + + + diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.rb index 0e6b5025..dd16b440 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.rb +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.rb @@ -87,6 +87,7 @@ def run(ws, runner, user_args) i += 1 end end + return true end end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.xml index 05e58d4a..e3645a9e 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_python_environment/measure.xml @@ -1,11 +1,10 @@ - 3.0 - uninitialized constant Python + 3.1 alfalfa_python_environment 16125428-fcf9-4986-9d9b-3644225a2b6d - 310e60b6-6215-4d58-b10b-e21eddaaf129 - 20221031T173904Z + 39ffcfe8-5902-44dd-9d1a-5aae2502d8c7 + 2024-05-03T20:06:06Z 9D2F1A23 AlfalfaPythonEnvironment Alfalfa Python Environment @@ -14,7 +13,9 @@ - + + Tool.Alfalfa + Measure Type @@ -37,7 +38,7 @@ measure.rb rb script - 4A5B6A8D + 91260911 diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_setpoint_control/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_setpoint_control/measure.xml index 2f396eb0..ee934f8c 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_setpoint_control/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_setpoint_control/measure.xml @@ -1,10 +1,11 @@ - 3.0 + 3.1 + Failed to infer measure name from '/Users/tshapins/Documents/Projects/alfalfa/alfalfa_worker/jobs/openstudio/lib/workflow/measures/./alfalfa_setpoint_control/measure.rb' alfalfa_setpoint_control 870213d3-36a2-4da2-9a04-c377a37fd4fe - bf35c981-cffe-41a8-ac34-606ebbc44c7d - 20230125T214417Z + 035cbac7-2f31-4ba1-a9ea-daf5250333ac + 2024-05-03T20:06:07Z 70995EFB AlfalfaSetpointControl Alfalfa Setpoint Control @@ -33,19 +34,7 @@ measure.rb rb script - 6F11EE21 - - - output.rb - rb - resource - 4553AB66 - - - input.rb - rb - resource - 9C7F46CA + 2453D3C6 diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_site_sensors/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_site_sensors/measure.xml index e1ac484d..e4070d78 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_site_sensors/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_site_sensors/measure.xml @@ -1,11 +1,11 @@ - 3.0 - cannot load such file -- alfalfa + 3.1 + Failed to infer measure name from '/Users/tshapins/Documents/Projects/alfalfa/alfalfa_worker/jobs/openstudio/lib/workflow/measures/./alfalfa_site_sensors/measure.rb' alfalfa_site_sensors 870213d3-36a2-4da2-9a04-c377a37fd4fe - f0fb23f6-6d8d-41a7-be6d-8d8f27416c33 - 20230127T210421Z + 40c05e7b-834f-41f7-857a-baf8e251ebf9 + 2024-05-03T20:06:06Z 70995EFB AlfalfaSiteSensors Alfalfa Site Sensors @@ -34,7 +34,7 @@ measure.rb rb script - 4FCE96E6 + FC5DA746 diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_zone_sensors/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_zone_sensors/measure.xml index 6f68f4fb..11677260 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_zone_sensors/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/alfalfa_zone_sensors/measure.xml @@ -1,11 +1,11 @@ - 3.0 - cannot load such file -- alfalfa + 3.1 + Failed to infer measure name from '/Users/tshapins/Documents/Projects/alfalfa/alfalfa_worker/jobs/openstudio/lib/workflow/measures/./alfalfa_zone_sensors/measure.rb' alfalfa_zone_sensors 870213d3-36a2-4da2-9a04-c377a37fd4fe - f0fb23f6-6d8d-41a7-be6d-8d8f27416c33 - 20230127T210421Z + df638ad5-4910-40df-bd19-09e407424262 + 2024-05-03T20:06:06Z 70995EFB AlfalfaZoneSensors Alfalfa Setpoint Control @@ -34,7 +34,7 @@ measure.rb rb script - 4FCE96E6 + 0977BFBC diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/export_bcvtb/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/export_bcvtb/measure.xml index 0d7b7f48..cc816017 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/export_bcvtb/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/export_bcvtb/measure.xml @@ -1,63 +1,65 @@ - - 3.0 - export_bcvtb - 7fb36b3a-5591-4627-a2b0-7709fbeae593 - 1c19cb5b-ac8f-4cfa-912c-de7e8a8b1d6a - 20170606T230141Z - A9D5932A - ExportBCVTB - ExportBCVTB - This measure will create the variables.cfg xml file for BCVTB - This measure loops through outputvariables, EMS:outputvariables and ExternalInterface objects and will create the variables.cfg xml file for BCVTB. - - - - - HVAC.Whole System - - - - Measure Type - ModelMeasure - string - - - Intended Software Tool - Apply Measure Now - string - - - Intended Software Tool - OpenStudio Application - string - - - Intended Software Tool - Parametric Analysis Tool - string - - - Intended Use Case - Model Articulation - string - - - Intended Use Case - New Construction EE - string - - - - - - OpenStudio - 1.12.2 - 1.12.2 - - measure.rb - rb - script - 49B31A9A - - - + + + 3.1 + Failed to infer measure name from '/Users/tshapins/Documents/Projects/alfalfa/alfalfa_worker/jobs/openstudio/lib/workflow/measures/./export_bcvtb/measure.rb' + export_bcvtb + 7fb36b3a-5591-4627-a2b0-7709fbeae593 + c92aa95d-9707-4ff9-8bc0-8ea7fbdf532c + 2024-05-03T20:06:07Z + A9D5932A + ExportBCVTB + ExportBCVTB + This measure will create the variables.cfg xml file for BCVTB + This measure loops through outputvariables, EMS:outputvariables and ExternalInterface objects and will create the variables.cfg xml file for BCVTB. + + + + + HVAC.Whole System + + + + Measure Type + ModelMeasure + string + + + Intended Software Tool + Apply Measure Now + string + + + Intended Software Tool + OpenStudio Application + string + + + Intended Software Tool + Parametric Analysis Tool + string + + + Intended Use Case + Model Articulation + string + + + Intended Use Case + New Construction EE + string + + + + + + OpenStudio + 1.12.2 + 1.12.2 + + measure.rb + rb + script + F60B3189 + + + diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/expose_time_variables/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/expose_time_variables/measure.xml index c764fff5..c238daa0 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/expose_time_variables/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/expose_time_variables/measure.xml @@ -1,75 +1,64 @@ - - 3.0 - expose_time_variable_240 - f31b5fc3-a70a-45de-ae01-b953f7a9b694 - 78d80dfc-a425-4c95-9483-095cbc75588a - 20181017T220232Z - FC9586A7 - ExposeTimeVariable240 - ExposeTimeVariable240 - This measure will output the built-in variables through EMS modules. - EMS:GlobalVariable; EMS:Subroutine; EMS:Program; EMS:ProgramCallingManager; EMS:OutputVariable; and Output:Variable - - - ExposeTime - ExposeTimeChoice? - Default=Yes - String - true - false - Yes - - - - - - Whole Building.Whole Building Schedules - - - - Measure Type - ModelMeasure - string - - - Intended Software Tool - Apply Measure Now - string - - - Intended Software Tool - OpenStudio Application - string - - - Intended Software Tool - Parametric Analysis Tool - string - - - - - expose_time_variable_240_test.rb - rb - test - D9408794 - - - example_model.osm - osm - test - 53D14E69 - - - - OpenStudio - 2.4.0 - 2.4.0 - - measure.rb - rb - script - 8EE297EF - - - + + + 3.1 + expose_time_variable_240 + f31b5fc3-a70a-45de-ae01-b953f7a9b694 + 31f3866c-d4b3-4be0-8042-60108cf4646f + 2024-05-03T20:06:07Z + FC9586A7 + ExposeTimeVariable240 + ExposeTimeVariable240 + This measure will output the built-in variables through EMS modules. + EMS:GlobalVariable; EMS:Subroutine; EMS:Program; EMS:ProgramCallingManager; EMS:OutputVariable; and Output:Variable + + + ExposeTime + ExposeTimeChoice? + Default=Yes + String + true + false + Yes + + + + + + Whole Building.Whole Building Schedules + + + + Measure Type + ModelMeasure + string + + + Intended Software Tool + Apply Measure Now + string + + + Intended Software Tool + OpenStudio Application + string + + + Intended Software Tool + Parametric Analysis Tool + string + + + + + + OpenStudio + 2.4.0 + 2.4.0 + + measure.rb + rb + script + 21A50C12 + + + diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/haystack/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/haystack/measure.xml index 941fc9b5..15d02b2c 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/measures/haystack/measure.xml +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/measures/haystack/measure.xml @@ -1,83 +1,84 @@ - - 3.0 - haystack - a3201f8c-bc3d-4fe1-a945-4a4f22471c06 - 967b2a78-232e-479d-bf84-f21e146f6737 - 20180109T180541Z - A9D5932A - Haystack - Haystack - This measure will find economizers on airloops and add haystack tags. - This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers - - - local_test - Local Test - Use EMS for Local Testing - Boolean - false - false - true - - - true - true - - - false - false - - - - - - - - HVAC.Whole System - - - - Measure Type - ModelMeasure - string - - - Intended Software Tool - Apply Measure Now - string - - - Intended Software Tool - OpenStudio Application - string - - - Intended Software Tool - Parametric Analysis Tool - string - - - Intended Use Case - Model Articulation - string - - - Intended Use Case - New Construction EE - string - - - - - - OpenStudio - 1.12.2 - 1.12.2 - - measure.rb - rb - script - 5D641FEE - - - + + + 3.1 + haystack + a3201f8c-bc3d-4fe1-a945-4a4f22471c06 + 267bef8f-bfdf-4784-872d-8bde1ca3d509 + 2024-05-03T20:06:06Z + A9D5932A + Haystack + Haystack + This measure will find economizers on airloops and add haystack tags. + This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers + + + local_test + Local Test + Use EMS for Local Testing + Boolean + false + false + true + + + true + true + + + false + false + + + + + + + + HVAC.Whole System + + + + Measure Type + ModelMeasure + string + + + Intended Software Tool + Apply Measure Now + string + + + Intended Software Tool + OpenStudio Application + string + + + Intended Software Tool + Parametric Analysis Tool + string + + + Intended Use Case + Model Articulation + string + + + Intended Use Case + New Construction EE + string + + + + + + OpenStudio + 1.12.2 + 1.12.2 + + measure.rb + rb + script + 931D5261 + + + diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/.gitignore b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/.gitignore deleted file mode 100644 index 40a4dddd..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -/.bundle/ -/.yardoc -/.ruby-version -/Gemfile.lock -/gems -/_yardoc/ -/coverage/ -/doc/ -/pkg/ -/spec/reports/ -/spec/test/ -/tmp/ -/test/ -/lib/measures/test_results -/lib/measures/.rubocop* - -# rspec failure tracking -.rspec_status - -# Ignore IDE files -/.idea -*.rubocop-http* - -# measures tests -lib/measures/.rubocop.yml -lib/measures/test_results/* - -# runner conf -runner.conf diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Gemfile b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Gemfile deleted file mode 100644 index 4f612982..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Gemfile +++ /dev/null @@ -1,44 +0,0 @@ -######################################################################################################################## -# Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -# following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following -# disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products -# derived from this software without specific prior written permission from the respective party. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED -# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -######################################################################################################################## - -source 'http://rubygems.org' - -gemspec - -# Local gems are useful when developing and integrating the various dependencies. -# To favor the use of local gems, set the following environment variable: -# Mac: export FAVOR_LOCAL_GEMS=1 -# Windows: set FAVOR_LOCAL_GEMS=1 -# Note that if allow_local is true, but the gem is not found locally, then it will -# checkout the latest version (develop) from github. -allow_local = ENV['FAVOR_LOCAL_GEMS'] - -if allow_local && File.exist?('../OpenStudio-extension-gem') - gem 'openstudio-extension', path: '../OpenStudio-extension-gem' -elsif allow_local - gem 'openstudio-extension', github: 'NREL/OpenStudio-extension-gem', branch: 'develop' -end - -gem 'openstudio_measure_tester', '= 0.2.0' # This includes the dependencies for running unit tests, coverage, and rubocop diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/README.md b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/README.md deleted file mode 100644 index 0ab8d668..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Openstudio Alfalfa Gem - -Extrapolation from the [Haystack measure](https://github.com/NREL/alfalfa/tree/develop/worker/workflow/measures/haystack) written for alfalfa - -## Installation - -Add this line to your application's Gemfile: - -```ruby -gem 'openstudio-alfalfa' -``` - -And then execute: - - $ bundle - -Or install it yourself as: - - $ gem install 'openstudio-alfalfa' - -## Usage - -To be filled out later. - -## TODO - -- [ ] Remove measures from OpenStudio-Measures to standardize on this location -- [ ] Update measures to code standards -- [ ] Review and fill out the gemspec file with author and gem description - -# Releasing - -- Update change log -- Update version in `/lib/openstudio/openstudio-alfalfa/version.rb` -- Merge down to master -- Release via github -- run `rake release` from master diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Rakefile b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Rakefile deleted file mode 100644 index e4a1e1f4..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/Rakefile +++ /dev/null @@ -1,40 +0,0 @@ -######################################################################################################################## -# Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -# following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following -# disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products -# derived from this software without specific prior written permission from the respective party. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED -# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -######################################################################################################################## - -require 'bundler/gem_tasks' -require 'rspec/core/rake_task' - -RSpec::Core::RakeTask.new(:spec) - -require 'rubocop/rake_task' -RuboCop::RakeTask.new - -# Load in the rake tasks from the base openstudio-extension gem -require 'openstudio/extension/rake_task' -require 'openstudio/alfalfa' -os_extension = OpenStudio::Extension::RakeTask.new -os_extension.set_extension_class(OpenStudio::Alfalfa::Alfalfa) - -task default: :spec diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/LICENSE.md b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/LICENSE.md deleted file mode 100644 index a9c578c2..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted -provided that the following conditions are met: - -(1) Redistributions of source code must retain the above copyright notice, this list of conditions -and the following disclaimer. - -(2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions -and the following disclaimer in the documentation and/or other materials provided with the distribution. - -(3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse -or promote products derived from this software without specific prior written permission from the -respective party. - -(4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other -derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar -designation without specific prior written permission from Alliance for Sustainable Energy, LLC. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES GOVERNMENT, -OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/README.md.erb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/README.md.erb deleted file mode 100644 index 2300680a..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/README.md.erb +++ /dev/null @@ -1,42 +0,0 @@ -<%#= README.md.erb is used to auto-generate README.md. %> -<%#= To manually maintain README.md throw away README.md.erb and manually edit README.md %> -###### (Automatically generated documentation) - -# <%= name %> - -## Description -<%= description %> - -## Modeler Description -<%= modelerDescription %> - -## Measure Type -<%= measureType %> - -## Taxonomy -<%= taxonomy %> - -## Arguments - -<% arguments.each do |argument| %> -### <%= argument[:display_name] %> -<%= argument[:description] %> -**Name:** <%= argument[:name] %>, -**Type:** <%= argument[:type] %>, -**Units:** <%= argument[:units] %>, -**Required:** <%= argument[:required] %>, -**Model Dependent:** <%= argument[:model_dependent] %> -<% end %> - -<% if arguments.size == 0 %> -<%= "This measure does not have any user arguments" %> -<% end %> - -<% if outputs.size > 0 %> -## Outputs -<% output_names = [] %> -<% outputs.each do |output| %> -<% output_names << output[:display_name] %> -<% end %> -<%= output_names.join(", ") %> -<% end %> diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_erb.txt b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_erb.txt deleted file mode 100644 index bb6f901a..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_erb.txt +++ /dev/null @@ -1,36 +0,0 @@ -<% - # ******************************************************************************* - # OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. - # All rights reserved. - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # - # (1) Redistributions of source code must retain the above copyright notice, - # this list of conditions and the following disclaimer. - # - # (2) Redistributions in binary form must reproduce the above copyright notice, - # this list of conditions and the following disclaimer in the documentation - # and/or other materials provided with the distribution. - # - # (3) Neither the name of the copyright holder nor the names of any contributors - # may be used to endorse or promote products derived from this software without - # specific prior written permission from the respective party. - # - # (4) Other than as required in clauses (1) and (2), distributions in any form - # of modifications or other derivative works may not use the "OpenStudio" - # trademark, "OS", "os", or any other confusingly similar designation without - # specific prior written permission from Alliance for Sustainable Energy, LLC. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE - # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF - # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # ******************************************************************************* -%> diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_js.txt b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_js.txt deleted file mode 100644 index 66140ccb..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_js.txt +++ /dev/null @@ -1,4 +0,0 @@ -/* @preserve - * OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be found at openstudio.net/license. -*/ diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_ruby.txt b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_ruby.txt deleted file mode 100644 index bd5b5d12..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/doc_templates/copyright_ruby.txt +++ /dev/null @@ -1,34 +0,0 @@ -# ******************************************************************************* -# OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. -# All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission from the respective party. -# -# (4) Other than as required in clauses (1) and (2), distributions in any form -# of modifications or other derivative works may not use the "OpenStudio" -# trademark, "OS", "os", or any other confusingly similar designation without -# specific prior written permission from Alliance for Sustainable Energy, LLC. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE -# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF -# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ******************************************************************************* diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.rb deleted file mode 100644 index e372f911..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.rb +++ /dev/null @@ -1,630 +0,0 @@ -######################################################################################################################## -# Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -# following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following -# disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products -# derived from this software without specific prior written permission from the respective party. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED -# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -######################################################################################################################## - -require 'json' -require 'openstudio/alfalfa' - -# start the measure -class Haystack < OpenStudio::Ruleset::ModelUserScript - - # human readable name - def name - return "Haystack" - end - - # human readable description - def description - return "This measure will find economizers on airloops and add haystack tags." - end - - # human readable description of modeling approach - def modeler_description - return "This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers" - end - - #define the arguments that the user will input - def arguments(model) - args = OpenStudio::Ruleset::OSArgumentVector.new - - local_test = OpenStudio::Ruleset::OSArgument::makeBoolArgument("local_test", false) - local_test.setDisplayName("Local Test") - local_test.setDescription("Use EMS for Local Testing") - local_test.setDefaultValue(true) - args << local_test - - return args - end #end the arguments method - - #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 not runner.validateUserArguments(arguments(model), user_arguments) - return false - end - - local_test = runner.getBoolArgumentValue("local_test",user_arguments) - runner.registerInfo("local_test = #{local_test}") - - #initialize tagger - tagger = OpenStudio::Alfalfa::Tagger.new - - #Global Vars - report_freq = "timestep" - - #initialize variables - haystack_json = [] - mapping_json = [] - num_economizers = 0 - airloops = [] - - #Master Enable - if local_test == false - #External Interface version - runner.registerInitialCondition("Initializing ExternalInterface") - master_enable = OpenStudio::Model::ExternalInterfaceVariable.new(model, "MasterEnable", 1) - #TODO uncomment out for real use - externalInterface = model.getExternalInterface - externalInterface.setNameofExternalInterface("PtolemyServer") - else - #EMS Version - runner.registerInitialCondition("Initializing EnergyManagementSystem") - master_enable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, "MasterEnable") - end - - #initialization program - program = OpenStudio::Model::EnergyManagementSystemProgram.new(model) - program.setName("Master_Enable") - program.addLine("SET #{master_enable.handle.to_s} = 1") - - pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model) - pcm.setName("Master_Enable_Prgm_Mgr") - pcm.setCallingPoint("BeginNewEnvironment") - pcm.addProgram(program) - - #Site and WeatherFile Data - if model.weatherFile.is_initialized - site_json = Hash.new - weather_json = Hash.new - floor_json = Hash.new - - wf = model.weatherFile.get - building = model.getBuilding - - site_json[:id] = tagger.create_ref(building.handle) - site_json[:dis] = tagger.tagger.create_str(building.name.to_s) - site_json[:site] = "m:" - site_json[:area] = tagger.tagger.create_num(building.floorArea) - site_json[:weatherRef] = tagger.create_ref(wf.handle) - site_json[:tz] = tagger.create_num(wf.timeZone) - site_json[:geoCity] = tagger.create_str(wf.city) - site_json[:geoState] = tagger.create_str(wf.stateProvinceRegion) - site_json[:geoCountry] = tagger.create_str(wf.country) - site_json[:geoCoord] = "c:#{wf.latitude},#{wf.longitude}" - site_json[:simStatus] = "s:Stopped" - site_json[:simType] = "s:osm" - haystack_json << site_json - - weather_json[:id] = tagger.create_ref(wf.handle) - weather_json[:dis] = tagger.create_str(wf.city) - weather_json[:weather] = "m:" - weather_json[:tz] = tagger.create_num(wf.timeZone) - weather_json[:geoCoord] = "c:#{wf.latitude},#{wf.longitude}" - haystack_json << weather_json - - #floor tag - simCon = model.getSimulationControl #use this for now until floors are defined - floor_json[:id] = tagger.create_ref(simCon.handle) - floor_json[:dis] = tagger.create_str("floor discription") - floor_json[:floor] = "m:" - haystack_json << floor_json - end - - ## Add tags to the time-variable outputs - ##output_vars = model.getOutputVariables - #output_vars = model.getEnergyManagementSystemOutputVariables - #output_vars_sorted = output_vars.sort_by{ |m| [ m.nameString.downcase]} - #output_vars_sorted.each do |outvar| - # #if (outvar.keyValue.to_s == "*") - # #print outvar - # print "\n The haystack tag is beding added to time-variables!!!" - # haystack_temp_json, temp_uuid = tagger.create_point_timevars(outvar, model.getBuilding.handle) - # haystack_json << haystack_temp_json - # temp_mapping = tagger.create_mapping_timevars(outvar,temp_uuid) - # mapping_json << temp_mapping - # #end - # - #end # end of do loop - - # Export all user defined OutputVariable objects - # as haystack sensor points - building = model.getBuilding - output_vars = model.getOutputVariables - output_vars.each do |outvar| - if outvar.exportToBCVTB - uuid = tagger.create_ref(outvar.handle) - - var_haystack_json = Hash.new - var_haystack_json[:id] = uuid - var_haystack_json[:dis] = tagger.create_str(outvar.nameString) - var_haystack_json[:siteRef] = tagger.create_ref(building.handle) - var_haystack_json[:point]="m:" - var_haystack_json[:cur]="m:" - var_haystack_json[:curStatus] = "s:disabled" - haystack_json << var_haystack_json - - var_map_json = Hash.new - var_map_json[:id] = uuid - var_map_json[:source] = "EnergyPlus" - var_map_json[:type] = outvar.variableName - var_map_json[:name] = outvar.keyValue - var_map_json[:variable] = "" - mapping_json << var_map_json - end - end - - # Export all user defined EnergyManagementSystemGlobalVariable objects - # as haystack writable points - global_vars = model.getEnergyManagementSystemGlobalVariables - global_vars.each do |globalvar| - if globalvar.exportToBCVTB - uuid = tagger.create_ref(globalvar.handle) - - if not globalvar.nameString.end_with?("_Enable") - var_haystack_json = Hash.new - var_haystack_json[:id] = uuid - var_haystack_json[:dis] = tagger.create_str(globalvar.nameString) - var_haystack_json[:siteRef] = tagger.create_ref(building.handle) - var_haystack_json[:point]="m:" - var_haystack_json[:writable]="m:" - var_haystack_json[:writeStatus] = "s:ok" - haystack_json << var_haystack_json - end - - var_mapping_json = Hash.new - var_mapping_json[:id] = uuid - var_mapping_json[:source] = "Ptolemy" - var_mapping_json[:name] = "" - var_mapping_json[:type] = "" - var_mapping_json[:variable] = globalvar.nameString - mapping_json << var_mapping_json - end - end - - #loop through air loops and find economizers - model.getAirLoopHVACs.each do |airloop| - supply_components = airloop.supplyComponents - #find AirLoopHVACOutdoorAirSystem on loop - supply_components.each do |supply_component| - sc = supply_component.to_AirLoopHVACOutdoorAirSystem - if sc.is_initialized - sc = sc.get - #get ControllerOutdoorAir - controller_oa = sc.getControllerOutdoorAir - #log initial economizer type - if not controller_oa.getEconomizerControlType == "NoEconomizer" - runner.registerInfo("found economizer on airloop #{airloop.name.to_s}") - #puts "found economizer on airloop #{airloop.name.to_s}" - num_economizers += 1 - end - end - end - end - - #loop through economizer loops and find fans and cooling coils - model.getAirLoopHVACs.each do |airloop| - ahu_json = tagger.create_ahu(airloop.handle,airloop.name.to_s, building.handle, simCon.handle) - - #AHU discharge sensors - #discharge air node - discharge_air_node = airloop.supplyOutletNode - #Temp Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Discharge Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "discharge", "air", "temp", "Number", "C") - haystack_json << haystack_temp_json - discharge_air_temp_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Temperature", discharge_air_node, "#{airloop.name.to_s} Discharge Air Temp Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - #Pressure Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Discharge Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, "discharge", "air", "pressure", "Number", "Pa") - haystack_json << haystack_temp_json - discharge_air_pressure_sensor = tagger.create_EMS_sensor("System Node Pressure", discharge_air_node, "#{airloop.name.to_s} Discharge Air Pressure Sensor", report_freq, model) - #Humidity Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Discharge Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "discharge", "air", "humidity", "Number", "%") - haystack_json << haystack_temp_json - discharge_air_humidity_sensor = tagger.create_EMS_sensor("System Node Relative Humidity", discharge_air_node, "#{airloop.name.to_s} Discharge Air Humidity Sensor", report_freq, model) - #Flow Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Discharge Air Flow Sensor", building.handle, airloop.handle, simCon.handle, "discharge", "air", "flow", "Number", "Kg/s") - haystack_json << haystack_temp_json - discharge_air_flow_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Mass Flow Rate", discharge_air_node, "#{airloop.name.to_s} Discharge Air Flow Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - - supply_components = airloop.supplyComponents - - #find fan, cooling coil and heating coil on loop - supply_components.each do |sc| - #get economizer on outdoor air system - if sc.to_AirLoopHVACOutdoorAirSystem.is_initialized - sc = sc.to_AirLoopHVACOutdoorAirSystem.get - #get ControllerOutdoorAir - controller_oa = sc.getControllerOutdoorAir - #create damper sensor and cmd points - damper_command = tagger.create_ems_str("#{airloop.name.to_s} Outside Air Damper CMD") - damper_command_enable = tagger.create_ems_str("#{airloop.name.to_s} Outside Air Damper CMD Enable") - damper_position = tagger.create_ems_str("#{airloop.name.to_s} Outside Air Damper Sensor position") - #Damper Sensor - haystack_temp_json, temp_uuid = tagger.create_point2_uuid("sensor", "position", damper_position, building.handle, airloop.handle, simCon.handle, "outside", "air", "damper", "Number", "%") - haystack_json << haystack_temp_json - outside_air_damper_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("Air System Outdoor Air Flow Fraction", airloop, "#{airloop.name.to_s} Outside Air Damper Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - - #add EMS Actuator for Damper - damper_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(controller_oa,"Outdoor Air Controller","Air Mass Flow Rate") - damper_actuator.setName(tagger.create_ems_str("#{airloop.name.to_s} Outside Air Mass Flow Rate")) - #Variable to read the Damper CMD - if local_test == false - #ExternalInterfaceVariables - damper_variable_enable = OpenStudio::Model::ExternalInterfaceVariable.new(model, damper_command_enable, 1) - mapping_json << tagger.create_mapping_output_uuid(damper_command_enable, damper_variable_enable.handle) - damper_variable = OpenStudio::Model::ExternalInterfaceVariable.new(model, damper_command, 0.5) - mapping_json << tagger.create_mapping_output_uuid(damper_command, damper_variable.handle) - #Damper CMD - haystack_temp_json = tagger.create_controlpoint2("cmd", "writable", damper_command, damper_variable.handle, building.handle, airloop.handle, simCon.handle, "outside", "air", "damper", "Number", "%") - haystack_json << haystack_temp_json - else - #EnergyManagementSystemVariables - damper_variable_enable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, "#{damper_command_enable}") - mapping_json << tagger.create_mapping_output_uuid(damper_command_enable, damper_variable_enable.handle) - damper_variable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, "#{damper_command}") - mapping_json << tagger.create_mapping_output_uuid(damper_command, damper_variable.handle) - #Damper CMD - haystack_temp_json = tagger.create_controlpoint2("cmd", "writable", damper_command, damper_variable.handle, building.handle, airloop.handle, simCon.handle, "outside", "air", "damper", "Number", "%") - haystack_json << haystack_temp_json - #initialization program - program = OpenStudio::Model::EnergyManagementSystemProgram.new(model) - program.setName("#{damper_command}_Prgm_init") - #Turn off for now - program.addLine("SET #{damper_variable_enable.handle.to_s} = 0") - program.addLine("SET #{damper_variable.handle.to_s} = 0.5") - - pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model) - pcm.setName("#{damper_command}_Prgm_Mgr_init") - pcm.setCallingPoint("BeginNewEnvironment") - pcm.addProgram(program) - end - #mixed air node - if sc.mixedAirModelObject.is_initialized - #AHU mixed sensors - #mixed air node - mix_air_node = sc.mixedAirModelObject.get.to_Node.get - runner.registerInfo("found mixed air node #{mix_air_node.name.to_s} on airloop #{airloop.name.to_s}") - #Temp Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Mixed Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "mixed", "air", "temp", "Number", "C") - haystack_json << haystack_temp_json - mixed_air_temp_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Temperature", mix_air_node, "#{airloop.name.to_s} Mixed Air Temp Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - #Pressure Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Mixed Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, "mixed", "air", "pressure", "Number", "Pa") - haystack_json << haystack_temp_json - mixed_air_pressure_sensor = tagger.create_EMS_sensor("System Node Pressure", mix_air_node, "#{airloop.name.to_s} Mixed Air Pressure Sensor", report_freq, model) - #Humidity Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Mixed Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "mixed", "air", "humidity", "Number", "%") - haystack_json << haystack_temp_json - mixed_air_humidity_sensor = tagger.create_EMS_sensor("System Node Relative Humidity", mix_air_node, "#{airloop.name.to_s} Mixed Air Humidity Sensor", report_freq, model) - #Flow Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Mixed Air Flow Sensor", building.handle, airloop.handle, simCon.handle, "mixed", "air", "flow", "Number", "Kg/s") - haystack_json << haystack_temp_json - mixed_air_flow_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Mass Flow Rate", mix_air_node, "#{airloop.name.to_s} Mixed Air Flow Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - end - #outdoor air node - if sc.outdoorAirModelObject.is_initialized - #AHU outside sensors - #outdoor air node - outdoor_air_node = sc.outdoorAirModelObject.get.to_Node.get - runner.registerInfo("found outdoor air node #{outdoor_air_node.name.to_s} on airloop #{airloop.name.to_s}") - #Temp Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Outside Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "outside", "air", "temp", "Number", "C") - haystack_json << haystack_temp_json - outside_air_temp_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Temperature", outdoor_air_node, "#{airloop.name.to_s} Outside Air Temp Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - #Pressure Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Outside Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, "outside", "air", "pressure", "Number", "Pa") - haystack_json << haystack_temp_json - outside_air_pressure_sensor = tagger.create_EMS_sensor("System Node Pressure", outdoor_air_node, "#{airloop.name.to_s} Outside Air Pressure Sensor", report_freq, model) - #Humidity Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Outside Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "outside", "air", "humidity", "Number", "%") - haystack_json << haystack_temp_json - outside_air_humidity_sensor = tagger.create_EMS_sensor("System Node Relative Humidity", outdoor_air_node, "#{airloop.name.to_s} Outside Air Humidity Sensor", report_freq, model) - #Flow Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Outside Air Flow Sensor", building.handle, airloop.handle, simCon.handle, "outside", "air", "flow", "Number", "Kg/s") - haystack_json << haystack_temp_json - outside_air_flow_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Mass Flow Rate", outdoor_air_node, "#{airloop.name.to_s} Outside Air Flow Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - end - #return air node - if sc.returnAirModelObject.is_initialized - #AHU return sensors - #return air node - return_air_node = sc.returnAirModelObject.get.to_Node.get - runner.registerInfo("found return air node #{return_air_node.name.to_s} on airloop #{airloop.name.to_s}") - #Temp Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Return Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "return", "air", "temp", "Number", "C") - haystack_json << haystack_temp_json - return_air_temp_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Temperature", return_air_node, "#{airloop.name.to_s} Return Air Temp Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - #Pressure Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Return Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, "return", "air", "pressure", "Number", "Pa") - haystack_json << haystack_temp_json - return_air_pressure_sensor = tagger.create_EMS_sensor("System Node Pressure", return_air_node, "#{airloop.name.to_s} Return Air Pressure Sensor", report_freq, model) - #Humidity Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Return Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "return", "air", "humidity", "Number", "%") - haystack_json << haystack_temp_json - return_air_humidity_sensor = tagger.create_EMS_sensor("System Node Relative Humidity", return_air_node, "#{airloop.name.to_s} Return Air Humidity Sensor", report_freq, model) - #Flow Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Return Air Flow Sensor", building.handle, airloop.handle, simCon.handle, "return", "air", "flow", "Number", "Kg/s") - haystack_json << haystack_temp_json - return_air_flow_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Mass Flow Rate", return_air_node, "#{airloop.name.to_s} Return Air Flow Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - end - #relief air node - if sc.reliefAirModelObject.is_initialized - #AHU exhaust sensors - #exhaust air node - exhaust_air_node = sc.reliefAirModelObject.get.to_Node.get - runner.registerInfo("found relief air node #{exhaust_air_node.name.to_s} on airloop #{airloop.name.to_s}") - #Temp Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Exhaust Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "exhaust", "air", "temp", "Number", "C") - haystack_json << haystack_temp_json - exhaust_air_temp_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Temperature", exhaust_air_node, "#{airloop.name.to_s} Exhaust Air Temp Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - #Pressure Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Exhaust Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, "exhaust", "air", "pressure", "Number", "Pa") - haystack_json << haystack_temp_json - exhaust_air_pressure_sensor = tagger.create_EMS_sensor("System Node Pressure", exhaust_air_node, "#{airloop.name.to_s} Exhaust Air Pressure Sensor", report_freq, model) - #Humidity Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Exhaust Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "exhaust", "air", "humidity", "Number", "%") - haystack_json << haystack_temp_json - exhaust_air_humidity_sensor = tagger.create_EMS_sensor("System Node Relative Humidity", exhaust_air_node, "#{airloop.name.to_s} Exhaust Air Humidity Sensor", report_freq, model) - #Flow Sensor - haystack_temp_json, temp_uuid = tagger.create_point_uuid("sensor", "#{airloop.name.to_s} Exhaust Air Flow Sensor", building.handle, airloop.handle, simCon.handle, "exhaust", "air", "flow", "Number", "Kg/s") - haystack_json << haystack_temp_json - exhaust_air_flow_sensor, temp_json = tagger.tagger.create_EMS_sensor_bcvtb("System Node Mass Flow Rate", exhaust_air_node, "#{airloop.name.to_s} Exhaust Air Flow Sensor", temp_uuid, report_freq, model) - mapping_json << temp_json - end - - #Program to set the Damper Position - program = OpenStudio::Model::EnergyManagementSystemProgram.new(model) - program.setName("#{damper_command}_Prgm") - program.addLine("SET #{damper_actuator.handle.to_s} = Null") - program.addLine("IF #{master_enable.handle.to_s} == 1") - program.addLine(" SET DampPos = #{damper_variable.handle.to_s}") - program.addLine(" SET MixAir = #{mixed_air_flow_sensor.handle.to_s}") - program.addLine(" IF #{damper_variable_enable.handle.to_s} == 1") - program.addLine(" SET #{damper_actuator.handle.to_s} = DampPos*MixAir") - program.addLine(" ENDIF") - program.addLine("ENDIF") - - pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model) - pcm.setName("#{damper_command}_Prgm_Mgr") - pcm.setCallingPoint("AfterPredictorAfterHVACManagers") - pcm.addProgram(program) - - #its a UnitarySystem so get sub components - elsif sc.to_AirLoopHVACUnitarySystem.is_initialized - sc = sc.to_AirLoopHVACUnitarySystem.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:rooftop] = "m:" - fan = sc.supplyFan - if fan.is_initialized - #AHU FAN equip - if fan.get.to_FanVariableVolume.is_initialized - runner.registerInfo("found VAV #{fan.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:variableVolume] = "m:" - haystack_json << tagger.create_fan(fan.get.handle, "#{fan.get.name.to_s}", building.handle, airloop.handle, simCon.handle, true) - else - runner.registerInfo("found CAV #{fan.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:constantVolume] = "m:" - haystack_json << tagger.create_fan(fan.get.handle, "#{fan.get.name.to_s}", building.handle, airloop.handle, simCon.handle, false) - end - end - cc = sc.coolingCoil - if cc.is_initialized - if cc.get.to_CoilCoolingWater.is_initialized || cc.get.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized - runner.registerInfo("found WATER #{cc.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:chilledWaterCool] = "m:" - if cc.get.plantLoop.is_initialized - pl = cc.get.plantLoop.get - ahu_json[:chilledWaterPlantRef] = tagger.create_ref(pl.handle) - end - if cc.get.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized - ahu_json[:heatPump] = "m:" - end - else - runner.registerInfo("found DX #{cc.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:dxCool] = "m:" - end - end - hc = sc.heatingCoil - if hc.is_initialized - if hc.get.to_CoilHeatingElectric.is_initialized - runner.registerInfo("found ELECTRIC #{hc.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:elecHeat] = "m:" - elsif hc.get.to_CoilHeatingGas.is_initialized - runner.registerInfo("found GAS #{hc.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:gasHeat] = "m:" - elsif hc.get.to_CoilHeatingWater.is_initialized || hc.get.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized - runner.registerInfo("found WATER #{hc.get.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:hotWaterHeat] = "m:" - if hc.get.plantLoop.is_initialized - pl = hc.get.plantLoop.get - ahu_json[:hotWaterPlantRef] = tagger.create_ref(pl.handle) - end - if hc.get.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized - ahu_json[:heatPump] = "m:" - end - end - end - #END UnitarySystem - elsif sc.to_FanConstantVolume.is_initialized - sc = sc.to_FanConstantVolume.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:constantVolume] = "m:" - haystack_json << tagger.create_fan(sc.handle, "#{sc.name.to_s}", building.handle, airloop.handle, simCon.handle, false) - elsif sc.to_FanVariableVolume.is_initialized - sc = sc.to_FanVariableVolume.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:variableVolume] = "m:" - haystack_json << tagger.create_fan(sc.handle, "#{sc.name.to_s}", building.handle, airloop.handle, simCon.handle, true) - elsif sc.to_FanOnOff.is_initialized - sc = sc.to_FanOnOff.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:constantVolume] = "m:" - haystack_json << tagger.create_fan(sc.handle, "#{sc.name.to_s}", building.handle, airloop.handle, simCon.handle, false) - elsif sc.to_CoilCoolingWater.is_initialized - sc = sc.to_CoilCoolingWater.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:chilledWaterCool] = "m:" - if sc.plantLoop.is_initialized - pl = sc.plantLoop.get - ahu_json[:chilledWaterPlantRef] = tagger.create_ref(pl.handle) - end - elsif sc.to_CoilHeatingWater.is_initialized - sc = sc.to_CoilHeatingWater.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:hotWaterHeat] = "m:" - if sc.plantLoop.is_initialized - pl = sc.plantLoop.get - ahu_json[:hotWaterPlantRef] = tagger.create_ref(pl.handle) - end - elsif sc.to_CoilHeatingElectric.is_initialized - sc = sc.to_CoilHeatingElectric.get - runner.registerInfo("found #{sc.name.to_s} on airloop #{airloop.name.to_s}") - ahu_json[:elecHeat] = "m:" - end - - end #end supplycomponents - - demand_components = airloop.demandComponents - demand_components.each do |dc| - if dc.to_ThermalZone.is_initialized - tz = dc.to_ThermalZone.get - #create sensor points - zone_json_temp, dummyvar = tagger.create_point_uuid("sensor", "#{tz.name.to_s} Zone Air Temp Sensor", building.handle, airloop.handle, simCon.handle, "zone", "air", "temp", "Number", "C") - zone_json_humidity, dummyvar = tagger.create_point_uuid("sensor", "#{tz.name.to_s} Zone Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, "zone", "air", "humidity", "Number", "%") - - if tz.thermostatSetpointDualSetpoint.is_initialized - if tz.thermostatSetpointDualSetpoint.get.coolingSetpointTemperatureSchedule.is_initialized - cool_thermostat = tz.thermostatSetpointDualSetpoint.get.coolingSetpointTemperatureSchedule.get - runner.registerInfo("found #{cool_thermostat.name.to_s} on airloop #{airloop.name.to_s} in thermalzone #{tz.name.to_s}") - zone_json_cooling, dummyvar = tagger.create_point_uuid("sp", "#{tz.name.to_s} Zone Air Cooling sp", building.handle, airloop.handle, simCon.handle, "zone", "air", "temp", "Number", "C") - zone_json_cooling[:cooling] = "m:" - end - if tz.thermostatSetpointDualSetpoint.get.heatingSetpointTemperatureSchedule.is_initialized - heat_thermostat = tz.thermostatSetpointDualSetpoint.get.heatingSetpointTemperatureSchedule.get - runner.registerInfo("found #{heat_thermostat.name.to_s} on airloop #{airloop.name.to_s} in thermalzone #{tz.name.to_s}") - zone_json_heating, dummyvar = tagger.create_point_uuid("sp", "#{tz.name.to_s} Zone Air Heating sp", building.handle, airloop.handle, simCon.handle, "zone", "air", "temp", "Number", "C") - zone_json_heating[:heating] = "m:" - end - end - zone_json_temp[:area] = tagger.create_num(tz.floorArea) - if tz.volume.is_initialized - zone_json_temp[:volume] = tagger.create_num(tz.volume) - else - zone_json_temp[:volume] = tagger.create_num(0) - end - zone_json_humidity[:area] = tagger.create_num(tz.floorArea) - if tz.volume.is_initialized - zone_json_humidity[:volume] = tagger.create_num(tz.volume) - else - zone_json_humidity[:volume] = tagger.create_num(0) - end - - tz.equipment.each do |equip| - if equip.to_AirTerminalSingleDuctVAVReheat.is_initialized - zone_json_temp[:vav] = "m:" - zone_json_humidity[:vav] = "m:" - zone_json_cooling[:vav] = "m:" - zone_json_heating[:vav] = "m:" - ahu_json[:vavZone] = "m:" - - vav_json = tagger.create_vav(equip.handle, equip.name.to_s, building.handle, airloop.handle, simCon.handle) - - #check reheat coil - rc = equip.to_AirTerminalSingleDuctVAVReheat.get.reheatCoil - if rc.to_CoilHeatingWater.is_initialized - rc = rc.to_CoilHeatingWater.get - runner.registerInfo("found #{rc.name.to_s} on airloop #{airloop.name.to_s}") - vav_json[:hotWaterReheat] = "m:" - if rc.plantLoop.is_initialized - pl = rc.plantLoop.get - vav_json[:hotWaterPlantRef] = tagger.create_ref(pl.handle) - end - elsif rc.to_CoilHeatingElectric.is_initialized - rc = rc.to_CoilHeatingElectric.get - runner.registerInfo("found #{rc.name.to_s} on airloop #{airloop.name.to_s}") - vav_json[:elecReheat] = "m:" - end - haystack_json << vav_json - #entering and discharge sensors - entering_node = equip.to_AirTerminalSingleDuctVAVReheat.get.inletModelObject.get.to_Node - haystack_json_temp, temp_uuid = tagger.create_point_uuid("sensor", "#{equip.name.to_s} Entering Air Temp Sensor", building.handle, equip.handle, simCon.handle, "entering", "air", "temp", "Number", "C") - haystack_json << haystack_json_temp - discharge_node = equip.to_AirTerminalSingleDuctVAVReheat.get.outletModelObject.get.to_Node - haystack_json_temp, temp_uuid = tagger.create_point_uuid("sensor", "#{equip.name.to_s} Discharge Air Temp Sensor", building.handle, equip.handle, simCon.handle, "discharge", "air", "temp", "Number", "C") - haystack_json << haystack_json_temp - avail_sch = discharge_node = equip.to_AirTerminalSingleDuctVAVReheat.get.availabilitySchedule - #TODO 'reheat cmd' - elsif equip.to_AirTerminalSingleDuctUncontrolled.is_initialized - ahu_json[:directZone] = "m:" - end - end - haystack_json << zone_json_temp - haystack_json << zone_json_humidity - haystack_json << zone_json_cooling - haystack_json << zone_json_heating - end #end thermalzone - end #end demandcomponents - haystack_json << ahu_json - - end #end airloops - - runner.registerFinalCondition("The building has #{num_economizers} economizers") - #write out the haystack json - File.open("./report_haystack.json","w") do |f| - f.write(haystack_json.to_json) - end - #write out the mapping json - File.open("./report_mapping.json","w") do |f| - f.write(mapping_json.to_json) - end - - return true - - end #end the run method - -end #end the measure - -# register the measure to be used by the application -Haystack.new.registerWithApplication diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.xml b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.xml deleted file mode 100644 index 941fc9b5..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/measures/haystack/measure.xml +++ /dev/null @@ -1,83 +0,0 @@ - - 3.0 - haystack - a3201f8c-bc3d-4fe1-a945-4a4f22471c06 - 967b2a78-232e-479d-bf84-f21e146f6737 - 20180109T180541Z - A9D5932A - Haystack - Haystack - This measure will find economizers on airloops and add haystack tags. - This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers - - - local_test - Local Test - Use EMS for Local Testing - Boolean - false - false - true - - - true - true - - - false - false - - - - - - - - HVAC.Whole System - - - - Measure Type - ModelMeasure - string - - - Intended Software Tool - Apply Measure Now - string - - - Intended Software Tool - OpenStudio Application - string - - - Intended Software Tool - Parametric Analysis Tool - string - - - Intended Use Case - Model Articulation - string - - - Intended Use Case - New Construction EE - string - - - - - - OpenStudio - 1.12.2 - 1.12.2 - - measure.rb - rb - script - 5D641FEE - - - diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio-alfalfa.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio-alfalfa.rb deleted file mode 100644 index e9796fc2..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio-alfalfa.rb +++ /dev/null @@ -1 +0,0 @@ -require 'openstudio/alfalfa' diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa.rb deleted file mode 100644 index c3ef94e0..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa.rb +++ /dev/null @@ -1,51 +0,0 @@ -# ******************************************************************************* -# OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. -# All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission from the respective party. -# -# (4) Other than as required in clauses (1) and (2), distributions in any form -# of modifications or other derivative works may not use the "OpenStudio" -# trademark, "OS", "os", or any other confusingly similar designation without -# specific prior written permission from Alliance for Sustainable Energy, LLC. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE -# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF -# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ******************************************************************************* - -require 'openstudio/extension' -require_relative 'alfalfa/tagger' -require_relative 'alfalfa/version' - -module OpenStudio - module Alfalfa - class Alfalfa < OpenStudio::Extension::Extension - # Override parent class - def initialize - super - - @root_dir = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..')) - end - end - end -end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/tagger.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/tagger.rb deleted file mode 100644 index 99f81343..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/tagger.rb +++ /dev/null @@ -1,232 +0,0 @@ -require 'json' - -module OpenStudio - module Alfalfa - class Tagger - - def initialize - - end - - def create_uuid(dummyinput) - return "r:#{OpenStudio.removeBraces(OpenStudio.createUUID)}" - end - - def create_ref(id) - #return string formatted for Ref (ie, "r:xxxxx") with uuid of object - #return "r:#{id.gsub(/[\s-]/,'_')}" - return "r:#{OpenStudio.removeBraces(id)}" - end - - def create_ref_name(id) - #return string formatted for Ref (ie, "r:xxxxx") with uuid of object - return "r:#{id.gsub(/[\s-]/, '_')}" - end - - def create_str(str) - #return string formatted for strings (ie, "s:xxxxx") - return "s:#{str}" - end - - def create_num(str) - #return string formatted for numbers (ie, "n:xxxxx") - return "n:#{str}" - end - - def create_ems_str(id) - #return string formatted with no spaces or '-' (can be used as EMS var name) - return "#{id.gsub(/[\s-]/, '_')}" - end - - def create_point_timevars(outvar_time, siteRef) - #this function will add haystack tag to the time-variables created by user. - #the time-variables are also written to variables.cfg file to coupling energyplus - #the uuid is unique to be used for mapping purpose - #the point_json generated here caontains the tags for the tim-variables - point_json = Hash.new - #id = outvar_time.keyValue.to_s + outvar_time.name.to_s - uuid = create_uuid("") - point_json[:id] = uuid - #point_json[:source] = create_str("EnergyPlus") - #point_json[:type] = "Output:Variable" - #point_json[:name] = create_str(outvar_time.name.to_s) - #point_json[:variable] = create_str(outvar_time.name) - point_json[:dis] = create_str(outvar_time.nameString) - point_json[:siteRef] = create_ref(siteRef) - point_json[:point] = "m:" - point_json[:cur] = "m:" - point_json[:curStatus] = "s:disabled" - - return point_json, uuid - end - - # end of create_point_timevar - - def create_mapping_timevars(outvar_time, uuid) - #this function will use the uuid generated from create_point_timevars(), to make a mapping. - #the uuid is unique to be used for mapping purpose; uuid is the belt to connect point_json and mapping_json - #the mapping_json below contains all the necessary tags - mapping_json = Hash.new - mapping_json[:id] = uuid - mapping_json[:source] = "EnergyPlus" - mapping_json[:name] = "EMS" - mapping_json[:type] = outvar_time.nameString - mapping_json[:variable] = "" - - return mapping_json - end - - - def create_point_uuid(type, id, siteRef, equipRef, floorRef, where, what, measurement, kind, unit) - point_json = Hash.new - uuid = create_uuid(id) - point_json[:id] = uuid - point_json[:dis] = create_str(id) - point_json[:siteRef] = create_ref(siteRef) - point_json[:equipRef] = create_ref(equipRef) - point_json[:floorRef] = create_ref(floorRef) - point_json[:point] = "m:" - point_json["#{type}"] = "m:" - point_json["#{measurement}"] = "m:" - point_json["#{where}"] = "m:" - point_json["#{what}"] = "m:" - point_json[:kind] = create_str(kind) - point_json[:unit] = create_str(unit) - point_json[:cur] = "m:" - point_json[:curStatus] = "s:disabled" - return point_json, uuid - end - - def create_point2_uuid(type, type2, id, siteRef, equipRef, floorRef, where, what, measurement, kind, unit) - point_json = Hash.new - uuid = create_uuid(id) - point_json[:id] = uuid - point_json[:dis] = create_str(id) - point_json[:siteRef] = create_ref(siteRef) - point_json[:equipRef] = create_ref(equipRef) - point_json[:floorRef] = create_ref(floorRef) - point_json[:point] = "m:" - point_json["#{type}"] = "m:" - point_json["#{type2}"] = "m:" - point_json["#{measurement}"] = "m:" - point_json["#{where}"] = "m:" - point_json["#{what}"] = "m:" - point_json[:kind] = create_str(kind) - point_json[:unit] = create_str(unit) - point_json[:cur] = "m:" - point_json[:curStatus] = "s:disabled" - return point_json, uuid - end - - def create_controlpoint2(type, type2, id, uuid, siteRef, equipRef, floorRef, where, what, measurement, kind, unit) - point_json = Hash.new - point_json[:id] = create_ref(uuid) - point_json[:dis] = create_str(id) - point_json[:siteRef] = create_ref(siteRef) - point_json[:equipRef] = create_ref(equipRef) - point_json[:floorRef] = create_ref(floorRef) - point_json[:point] = "m:" - point_json["#{type}"] = "m:" - point_json["#{type2}"] = "m:" - point_json["#{measurement}"] = "m:" - point_json["#{where}"] = "m:" - point_json["#{what}"] = "m:" - point_json[:kind] = create_str(kind) - point_json[:unit] = create_str(unit) - if type2 == "writable" - point_json[:writeStatus] = "s:ok" - end - return point_json - end - - def create_fan(id, name, siteRef, equipRef, floorRef, variable) - point_json = Hash.new - point_json[:id] = create_ref(id) - point_json[:dis] = create_str(name) - point_json[:siteRef] = create_ref(siteRef) - point_json[:equipRef] = create_ref(equipRef) - point_json[:floorRef] = create_ref(floorRef) - point_json[:equip] = "m:" - point_json[:fan] = "m:" - if variable - point_json[:vfd] = "m:" - point_json[:variableVolume] = "m:" - else - point_json[:constantVolume] = "m:" - end - return point_json - end - - def create_ahu(id, name, siteRef, floorRef) - ahu_json = Hash.new - ahu_json[:id] = create_ref(id) - ahu_json[:dis] = create_str(name) - ahu_json[:ahu] = "m:" - ahu_json[:hvac] = "m:" - ahu_json[:equip] = "m:" - ahu_json[:siteRef] = create_ref(siteRef) - ahu_json[:floorRef] = create_ref(floorRef) - return ahu_json - end - - def create_vav(id, name, siteRef, equipRef, floorRef) - vav_json = Hash.new - vav_json[:id] = create_ref(id) - vav_json[:dis] = create_str(name) - vav_json[:hvac] = "m:" - vav_json[:vav] = "m:" - vav_json[:equip] = "m:" - vav_json[:equipRef] = create_ref(equipRef) - vav_json[:ahuRef] = create_ref(equipRef) - vav_json[:siteRef] = create_ref(siteRef) - vav_json[:floorRef] = create_ref(floorRef) - return vav_json - end - - def create_mapping_output_uuid(emsName, uuid) - json = Hash.new - json[:id] = create_ref(uuid) - json[:source] = "Ptolemy" - json[:name] = "" - json[:type] = "" - json[:variable] = emsName - return json - end - - def create_EMS_sensor_bcvtb(outVarName, key, emsName, uuid, report_freq, model) - outputVariable = OpenStudio::Model::OutputVariable.new(outVarName, model) - outputVariable.setKeyValue("#{key.name.to_s}") - outputVariable.setReportingFrequency(report_freq) - outputVariable.setName(outVarName) - outputVariable.setExportToBCVTB(true) - - sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, outputVariable) - sensor.setKeyName(key.handle.to_s) - sensor.setName(create_ems_str(emsName)) - - json = Hash.new - json[:id] = uuid - json[:source] = "EnergyPlus" - json[:type] = outVarName - json[:name] = key.name.to_s - json[:variable] = "" - return sensor, json - end - - #will get deprecated by 'create_EMS_sensor_bcvtb' once Master Algo debugged (dont clutter up the json's with unused points right now) - def create_EMS_sensor(outVarName, key, emsName, report_freq, model) - outputVariable = OpenStudio::Model::OutputVariable.new(outVarName, model) - outputVariable.setKeyValue("#{key.name.to_s}") - outputVariable.setReportingFrequency(report_freq) - outputVariable.setName(outVarName) - sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, outputVariable) - sensor.setKeyName(key.handle.to_s) - sensor.setName(create_ems_str(emsName)) - return sensor - end - - end - - end - -end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/version.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/version.rb deleted file mode 100644 index bce02825..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/lib/openstudio/alfalfa/version.rb +++ /dev/null @@ -1,40 +0,0 @@ -# ******************************************************************************* -# OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. -# All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission from the respective party. -# -# (4) Other than as required in clauses (1) and (2), distributions in any form -# of modifications or other derivative works may not use the "OpenStudio" -# trademark, "OS", "os", or any other confusingly similar designation without -# specific prior written permission from Alliance for Sustainable Energy, LLC. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE -# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF -# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ******************************************************************************* - -module OpenStudio - module Alfalfa - VERSION = '0.0.1'.freeze - end -end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/openstudio-alfalfa.gemspec b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/openstudio-alfalfa.gemspec deleted file mode 100644 index e8c99a50..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/openstudio-alfalfa.gemspec +++ /dev/null @@ -1,56 +0,0 @@ -######################################################################################################################## -# Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -# following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following -# disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products -# derived from this software without specific prior written permission from the respective party. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED -# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -######################################################################################################################## - -lib = File.expand_path('lib', __dir__) -$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'openstudio/alfalfa/version' - -Gem::Specification.new do |spec| - spec.name = 'openstudio-alfalfa' - spec.version = OpenStudio::Alfalfa::VERSION - spec.authors = ['Austin Viveiros'] - spec.email = [''] - - spec.summary = 'library and measures for OpenStudio' - spec.description = 'library and measures for OpenStudio' - spec.homepage = 'https://openstudio.net' - - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.bindir = 'exe' - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ['lib'] - - spec.add_development_dependency 'bundler', '~> 2.1.0' - spec.add_development_dependency 'rake', '>= 12.3.3' - spec.add_development_dependency 'rspec', '3.7.0' - spec.add_development_dependency 'rubocop', '~> 0.54.0' - - spec.add_dependency 'openstudio-extension', '~> 0.2.0' - spec.add_dependency 'openstudio-standards', '~> 0.2.7' -end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/spec_helper.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/spec_helper.rb deleted file mode 100644 index a77c0ebd..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/spec/spec_helper.rb +++ /dev/null @@ -1,49 +0,0 @@ -# ******************************************************************************* -# OpenStudio(R), Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC. -# All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission from the respective party. -# -# (4) Other than as required in clauses (1) and (2), distributions in any form -# of modifications or other derivative works may not use the "OpenStudio" -# trademark, "OS", "os", or any other confusingly similar designation without -# specific prior written permission from Alliance for Sustainable Energy, LLC. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE -# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF -# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ******************************************************************************* - -require 'bundler/setup' -require 'openstudio/alfalfa' - -RSpec.configure do |config| - # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = '.rspec_status' - - # Disable RSpec exposing methods globally on `Module` and `main` - config.disable_monkey_patching! - - config.expect_with :rspec do |c| - c.syntax = :expect - end -end diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/test.rb b/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/test.rb deleted file mode 100644 index aceeeab4..00000000 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/openstudio-alfalfa-gem/test.rb +++ /dev/null @@ -1,40 +0,0 @@ -######################################################################################################################## -# Copyright (c) 2008-2022, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -# following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following -# disclaimer. -# -# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided with the distribution. -# -# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products -# derived from this software without specific prior written permission from the respective party. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED -# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -######################################################################################################################## - -#require 'bundler/gem_tasks' -#require 'rspec/core/rake_task' -# -#RSpec::Core::RakeTask.new(:spec) -# -#require 'rubocop/rake_task' -#RuboCop::RakeTask.new -# -## Load in the rake tasks from the base openstudio-extension gem -require 'openstudio/extension/rake_task' -#require 'openstudio/alfalfa' -#os_extension = OpenStudio::Extension::RakeTask.new -#os_extension.set_extension_class(OpenStudio::Alfalfa::Alfalfa) -# -#task default: :spec diff --git a/alfalfa_worker/jobs/openstudio/lib/workflow/workflow.osw b/alfalfa_worker/jobs/openstudio/lib/workflow/workflow.osw index ec8b6f77..bb57955f 100644 --- a/alfalfa_worker/jobs/openstudio/lib/workflow/workflow.osw +++ b/alfalfa_worker/jobs/openstudio/lib/workflow/workflow.osw @@ -59,6 +59,13 @@ "name" : "Metadata", "description" : "Generate metadata report for Alfalfa", "modeler_description" : "Generate metadata report for Alfalfa" + }, + { + "arguments" : {}, + "measure_dir_name" : "alfalfa_prepare_idf", + "name": "Alfalfa Prepare IDF", + "description" : "Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution", + "modeler_description" : "Remove RunPeriod and Timestep IDF Objects in preparation for Alfalfa execution" } ], "updated_at" : "20170606T230145Z", diff --git a/alfalfa_worker/jobs/openstudio/step_run.py b/alfalfa_worker/jobs/openstudio/step_run.py index c70fe421..d013a36d 100644 --- a/alfalfa_worker/jobs/openstudio/step_run.py +++ b/alfalfa_worker/jobs/openstudio/step_run.py @@ -205,71 +205,33 @@ def get_sim_time(self): return sim_time + timedelta(hours=hour, minutes=minute % 60) def replace_timestep_and_run_period_idf_settings(self): + try: - # Generate Lines - begin_month_line = ' {}, !- Begin Month\n'.format( - self.start_datetime.month) - begin_day_line = ' {}, !- Begin Day of Month\n'.format( - self.start_datetime.day) - end_month_line = ' {}, !- End Month\n'.format(self.end_datetime.month) - end_day_line = ' {}, !- End Day of Month\n'.format( - self.end_datetime.day) - time_step_line = ' {}; !- Number of Timesteps per Hour\n'.format( - self.time_steps_per_hour) - begin_year_line = ' {}, !- Begin Year\n'.format(self.start_datetime.year) - end_year_line = ' {}, !- End Year\n'.format(self.end_datetime.year) - dayOfweek_line = ' {}, !- Day of Week for Start Day\n'.format( - self.start_datetime.strftime("%A")) - line_timestep = None # Sanity check to make sure object exists - line_runperiod = None # Sanity check to make sure object exists - - # Overwrite File - # the basic idea is to locate the pattern first (e.g. Timestep, RunPeriod) - # then find the relevant lines by counting how many lines away from the patten. - count = -1 - with open(self.idf_file, 'r+') as f: - lines = f.readlines() - f.seek(0) - f.truncate() - for line in lines: - count = count + 1 - if line.strip() == 'RunPeriod,': # Equivalency statement necessary - line_runperiod = count - if line.strip() == 'Timestep,': # Equivalency statement necessary - line_timestep = count + 1 - - if not line_timestep: - raise TypeError( - "line_timestep cannot be None. 'Timestep,' should be present in IDF file, but is not.") - - if not line_runperiod: - raise TypeError( - "line_runperiod cannot be None. 'RunPeriod,' should be present in IDF file, but is not.") - - for i, line in enumerate(lines): - if (i < line_runperiod or i > line_runperiod + 12) and (i != line_timestep): - f.write(line) - elif i == line_timestep: - line = time_step_line - f.write(line) - else: - if i == line_runperiod + 2: - line = begin_month_line - elif i == line_runperiod + 3: - line = begin_day_line - elif i == line_runperiod + 4: - line = begin_year_line - elif i == line_runperiod + 5: - line = end_month_line - elif i == line_runperiod + 6: - line = end_day_line - elif i == line_runperiod + 7: - line = end_year_line - elif i == line_runperiod + 8: - line = dayOfweek_line - else: - line = lines[i] - f.write(line) + runperiod_str = f""" +RunPeriod, + Alfalfa Run Period, + {self.start_datetime.month}, !- Begin Month + {self.start_datetime.day}, !- Begin Day of Month + {self.start_datetime.year}, !- Begin Year + {self.end_datetime.month}, !- End Month + {self.end_datetime.day}, !- End Day of Month + {self.end_datetime.year}, !- End Year + {self.start_datetime.strftime("%A")}, !- Day of Week for Start Day + , !- Use Weather File Holidays and Special Days + , !- Use Weather File Daylight Saving Period + , !- Apply Weekend Holiday Rule + , !- Use Weather File Rain Indicators + , !- Use Weather File Snow Indicators + , !- Treat Weather as Actual + ; !- First Hour Interpolation Starting Values""" + + timestep_str = f""" +Timestep, + {self.time_steps_per_hour}; !- Number of Timesteps per Hour""" + + with self.idf_file.open("a") as idf_file: + idf_file.write(runperiod_str) + idf_file.write(timestep_str) except BaseException as e: self.logger.error('Unsuccessful in replacing values in idf file. Exception: {}'.format(e)) raise JobException('Unsuccessful in replacing values in idf file. Exception: {}'.format(e)) diff --git a/alfalfa_worker/lib/testcase.py b/alfalfa_worker/lib/testcase.py index 9074a7c8..73a7a900 100644 --- a/alfalfa_worker/lib/testcase.py +++ b/alfalfa_worker/lib/testcase.py @@ -60,7 +60,7 @@ def __init__(self, **kwargs): # Define simulation model self.fmupath = init_options['fmupath'] # Load fmu - self.fmu = load_fmu(self.fmupath, enable_logging=True) + self.fmu = load_fmu(self.fmupath, log_level=1) # Get version and check is 2.0 self.fmu_version = self.fmu.get_version() if self.fmu_version != '2.0': diff --git a/tests/integration/models/refrig_case_osw/in.idf b/tests/integration/models/refrig_case_osw/in.idf index 90b5dc13..d3ab0867 100644 --- a/tests/integration/models/refrig_case_osw/in.idf +++ b/tests/integration/models/refrig_case_osw/in.idf @@ -1,4 +1,4 @@ - Version,23.1; + Version,24.1; Building, Refrig Case Model, !- Name @@ -276,7 +276,7 @@ Light Sch, !- Schedule Name Watts/Area, !- Design Level Calculation Method , !- Lighting Level {W} - 10.764, !- Watts per Zone Floor Area {W/m2} + 10.764, !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Return Air Fraction 0.7, !- Fraction Radiant @@ -289,7 +289,7 @@ Always On, !- Schedule Name EquipmentLevel, !- Design Level Calculation Method 500, !- Design Level {W} - , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Floor Area {W/m2} , !- Watts per Person {W/person} 0, !- Fraction Latent 0.7, !- Fraction Radiant @@ -562,6 +562,7 @@ , !- No Load Fraction of Autosized Heating Supply Air Flow Rate , !- No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation {m3/s-W} , !- No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation {m3/s-W} + No, !- No Load Supply Air Flow Rate Control Set To Low Speed 80; !- Maximum Supply Air Temperature {C} OutdoorAir:Node, @@ -605,6 +606,7 @@ , !- Evaporative Condenser Air Flow Rate {m3/s} , !- Evaporative Condenser Pump Rated Power Consumption {W} 0, !- Crankcase Heater Capacity {W} + , !- Crankcase Heater Capacity Function of Temperature Curve Name 10, !- Maximum Outdoor Dry-Bulb Temperature for Crankcase Heater Operation {C} , !- Supply Water Storage Tank Name , !- Condensate Collection Water Storage Tank Name diff --git a/tests/integration/models/refrig_case_osw/measures/alfalfa_vars/measure.xml b/tests/integration/models/refrig_case_osw/measures/alfalfa_vars/measure.xml index 21a6a2ad..b46bd3a2 100644 --- a/tests/integration/models/refrig_case_osw/measures/alfalfa_vars/measure.xml +++ b/tests/integration/models/refrig_case_osw/measures/alfalfa_vars/measure.xml @@ -1,10 +1,10 @@ - 3.0 + 3.1 alfalfa_variables 86d51823-68a5-478a-b60b-60891c3c9b5f - 5c94ef46-d8e9-4ae9-864e-d884aba51509 - 20201216T214230Z + 8752f0cc-7f4d-4d58-af81-511e93aef0cd + 2024-05-03T20:14:25Z 356BE47F AlfalfaVariables AlfalfaVariables @@ -48,7 +48,7 @@ measure.rb rb script - A9E1EEF2 + 2A97F3D3 diff --git a/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.rb b/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.rb index 5f605227..e534638d 100644 --- a/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.rb +++ b/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.rb @@ -93,6 +93,7 @@ def run(workspace,runner,usr_args) end runner.workflow.absoluteFilePaths.each {|p| o.setString(6,p.to_s) if p.to_s.include?('python')} end + return true end end diff --git a/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.xml b/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.xml index 8b3faae6..73588b29 100644 --- a/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.xml +++ b/tests/integration/models/refrig_case_osw/measures/prep_idf/measure.xml @@ -1,10 +1,10 @@ - 3.0 + 3.1 prepare_idf 28ad6cb2-e1e3-4f7c-82ab-8ef22aca2c39 - 6e75d5c3-39ee-45ba-b7f1-d5c57722c3c7 - 20201216T214230Z + 7c27abba-ecad-48c8-b67f-ee1e269447da + 2024-05-03T20:14:25Z 9D2F1A23 PrepareIDF Prepare IDF @@ -23,7 +23,9 @@ - + + Tool.Alfalfa + Measure Type @@ -46,7 +48,7 @@ measure.rb rb script - 0D590B51 + 3F126612 diff --git a/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.rb b/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.rb index e9d87407..68760bac 100644 --- a/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.rb +++ b/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.rb @@ -113,6 +113,7 @@ def run(workspace,runner,usr_args) workspace.addObjects(ext_workspace.toIdfFile.objects) # report final condition of model runner.registerFinalCondition("The final IDF file had #{workspace.objects.size} objects.") + return true end end diff --git a/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.xml b/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.xml index a9bd9f98..7c757931 100644 --- a/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.xml +++ b/tests/integration/models/refrig_case_osw/measures/replace_idf/measure.xml @@ -1,11 +1,11 @@ - 3.0 + 3.1 replace_idf 256ee271-1946-4ee6-9ec2-26cd94fe5dfc - b6c2f463-75e8-4934-a802-ceee30b74be5 - 20201216T214230Z - 9D2F1A23 + cb60e4b5-42ac-4d98-b9ff-e87f3b36a170 + 2024-05-03T20:41:47Z + 7A4781A5 ReplaceIDF Replace IDF Replace OpenStudio generated IDF file with user specified IDF. @@ -22,7 +22,9 @@ - + + Tool.Alfalfa + Measure Type @@ -45,7 +47,7 @@ measure.rb rb script - E1C73E0E + DCCC3510 diff --git a/tests/integration/models/small_office/measures/python_ems/measure.rb b/tests/integration/models/small_office/measures/python_ems/measure.rb index a84a0e66..c7522fda 100644 --- a/tests/integration/models/small_office/measures/python_ems/measure.rb +++ b/tests/integration/models/small_office/measures/python_ems/measure.rb @@ -5,21 +5,21 @@ class PythonEMS < OpenStudio::Ruleset::WorkspaceUserScript def name return 'Python EMS' end - + # human readable description def description return 'Add python EMS to IDF' end - + # human readable description of modeling approach def modeler_description return 'Add python EMS to IDF' end - + # define the arguments that the user will input def arguments(ws) args = OpenStudio::Ruleset::OSArgumentVector.new - + # argument for python script name py_name = OpenStudio::Ruleset::OSArgument.makeStringArgument( 'py_name', @@ -37,22 +37,22 @@ def arguments(ws) args << py_name args << class_name - + return args end - + # define what happens when the measure is run def run(ws, runner, usr_args) - + # call the parent class method super(ws, runner, usr_args) - + # use the built-in error checking return false unless runner.validateUserArguments( arguments(ws), usr_args ) - + # assign the user inputs to variables py_name = runner.getStringArgumentValue( 'py_name', @@ -63,16 +63,16 @@ def run(ws, runner, usr_args) 'class_name', usr_args ) - + # define python script dir py_dir = "#{__dir__}/resources" - + # make sure python script exists unless File.exist?("#{py_dir}/#{py_name}") runner.registerError("Could not find file at #{py_dir}/#{py_name}.") return false end - + # add python plugin search paths n = OpenStudio::IdfObject.new('PythonPlugin_SearchPaths'.to_IddObjectType) n.setString(0, 'Python Plugin Search Paths') @@ -90,7 +90,7 @@ def run(ws, runner, usr_args) # add python dir n.setString(5, py_dir) ws.addObject(n) - + # add python plugin instance n = OpenStudio::IdfObject.new('PythonPlugin_Instance'.to_IddObjectType) n.setString(0, 'Python Plugin Instance Name') @@ -98,10 +98,12 @@ def run(ws, runner, usr_args) n.setString(2, py_name.sub('.py', '')) n.setString(3, class_name) ws.addObject(n) - + + return true + end - + end - + # register the measure to be used by the application - PythonEMS.new.registerWithApplication \ No newline at end of file + PythonEMS.new.registerWithApplication diff --git a/tests/integration/models/small_office/measures/python_ems/measure.xml b/tests/integration/models/small_office/measures/python_ems/measure.xml index 4706f5b9..4f8df195 100644 --- a/tests/integration/models/small_office/measures/python_ems/measure.xml +++ b/tests/integration/models/small_office/measures/python_ems/measure.xml @@ -22,7 +22,9 @@ - + + Tool.Alfalfa + Measure Type