openstudio-analysis 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -6
  3. data/README.md +55 -7
  4. data/Rakefile +10 -0
  5. data/lib/openstudio/analysis/algorithm_attributes.rb +22 -0
  6. data/lib/openstudio/analysis/formulation.rb +174 -0
  7. data/lib/openstudio/analysis/translator/excel.rb +65 -48
  8. data/lib/openstudio/analysis/version.rb +1 -1
  9. data/lib/openstudio/analysis/workflow.rb +197 -0
  10. data/lib/openstudio/analysis/workflow_step.rb +312 -0
  11. data/lib/openstudio/analysis.rb +8 -0
  12. data/lib/openstudio/helpers/string.rb +22 -22
  13. data/lib/openstudio/templates/analysis.json.erb +0 -1
  14. data/lib/openstudio-analysis.rb +9 -0
  15. data/spec/files/0_1_09_small_list_incomplete.xlsx +0 -0
  16. data/spec/files/0_2_0_template_simpletest.xlsx +0 -0
  17. data/spec/files/0_4_0_lhs_discrete_continuous.xlsx +0 -0
  18. data/spec/files/analysis/example_analysis_api.json +656 -0
  19. data/spec/files/analysis/examples/discrete_lhs_example.json +809 -0
  20. data/spec/files/analysis/examples/medium_office_example.json +1673 -0
  21. data/spec/files/analysis/lhs_discrete_and_continuous_variables_api.json +1230 -0
  22. data/spec/files/analysis/medium_office.json +91 -92
  23. data/spec/files/analysis/medium_office.zip +0 -0
  24. data/spec/files/analysis/name_goes_here_api.json +1681 -0
  25. data/spec/files/analysis/output_vars_api.json +632 -0
  26. data/spec/files/analysis/preflight_api.json +1518 -0
  27. data/spec/files/analysis/simple_test_api.json +519 -0
  28. data/spec/files/analysis/test_model_api.json +493 -0
  29. data/spec/files/export/analysis/0_1_09_outputvars.json +38 -39
  30. data/spec/files/export/analysis/0_1_09_outputvars.zip +0 -0
  31. data/spec/files/export/analysis/0_1_11_discrete_variables.json +46 -47
  32. data/spec/files/export/analysis/0_1_11_discrete_variables.zip +0 -0
  33. data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.json +8 -9
  34. data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.zip +0 -0
  35. data/spec/files/export/analysis/0_2_0_template_simpletest.json +19 -14
  36. data/spec/files/export/analysis/0_2_0_template_simpletest.zip +0 -0
  37. data/spec/files/export/analysis/0_3_0_outputs.json +99 -100
  38. data/spec/files/export/analysis/0_3_0_outputs.zip +0 -0
  39. data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.json → 276ccf51-ed22-4604-a380-8985cec5efe8.json} +103 -104
  40. data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.zip → 276ccf51-ed22-4604-a380-8985cec5efe8.zip} +0 -0
  41. data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.json → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.json} +107 -108
  42. data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.zip → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.zip} +0 -0
  43. data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.json → 9560f95b-5730-4038-a95b-328c825c596b.json} +99 -100
  44. data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.zip → 9560f95b-5730-4038-a95b-328c825c596b.zip} +0 -0
  45. data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.json → c50f0062-cdfb-4dec-bc02-215f6c29af3c.json} +107 -108
  46. data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.zip → c50f0062-cdfb-4dec-bc02-215f6c29af3c.zip} +0 -0
  47. data/spec/files/export/analysis/discrete_lhs_example.json +1185 -0
  48. data/spec/files/export/analysis/discrete_lhs_example.zip +0 -0
  49. data/spec/files/export/analysis/small_seed.json +38 -39
  50. data/spec/files/export/analysis/small_seed.zip +0 -0
  51. data/spec/files/export/workflow/analysis.json +23 -0
  52. data/spec/files/measures/ActualMeasureNoJson/measure.json +25 -0
  53. data/spec/files/measures/ActualMeasureNoJson/measure.rb +80 -0
  54. data/spec/files/measures/ActualMeasureNoJson/measure.xml +2 -0
  55. data/spec/files/measures/SetThermostatSchedules/measure.json +63 -0
  56. data/spec/files/measures/SetThermostatSchedules/measure.rb +254 -0
  57. data/spec/files/measures/SetThermostatSchedules/measure.xml +2 -0
  58. data/spec/openstudio/excel_spec.rb +11 -11
  59. data/spec/openstudio/formulation_spec.rb +107 -0
  60. data/spec/openstudio/workflow_spec.rb +90 -0
  61. data/spec/openstudio/workflow_step_spec.rb +116 -0
  62. data/spec/reports/SPEC-OpenStudio-Analysis-Formulation.xml +28 -0
  63. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-object-instance.xml +2 -2
  64. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.xml +2 -2
  65. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.xml +1 -1
  66. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.xml +30 -4
  67. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.xml +11 -3
  68. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.xml +6 -6
  69. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.xml +2 -2
  70. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.xml +2 -2
  71. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.xml +52 -8
  72. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.xml +22 -5
  73. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.xml +2 -2
  74. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.xml +2 -2
  75. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.xml +28 -5
  76. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.xml +2 -2
  77. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.xml +3 -3
  78. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.xml +13 -6
  79. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.xml +55 -5
  80. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-dynamic-uuid-assignments.xml +9 -4
  81. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-measure-existence-checks.xml +8 -3
  82. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-objective-functions.xml +13 -5
  83. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-3-and-short-display-names.xml +9 -4
  84. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-5-and-measure-paths.xml +9 -4
  85. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.0.xml +40 -2
  86. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.xml +9 -4
  87. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.xml +1 -1
  88. data/spec/reports/SPEC-OpenStudio-Analysis-Workflow.xml +31 -0
  89. data/spec/reports/SPEC-OpenStudio-Analysis-WorkflowStep.xml +29 -0
  90. data/spec/spec_helper.rb +1 -1
  91. metadata +87 -18
@@ -14,14 +14,13 @@
14
14
 
15
15
  ]
16
16
  },
17
- "name": "Problem",
18
17
  "workflow": [
19
18
  {
20
19
  "measure_definition_class_name": "ReduceLightingLoadsByPercentage",
21
20
  "measure_definition_directory": "./measures/reduce_lighting_loads_by_percentage",
22
21
  "measure_definition_display_name": "ReduceLightingLoadsByPercentage",
23
- "measure_definition_uuid": "35714f63-9663-4406-8142-a6d969554f77",
24
- "measure_definition_version_uuid": "7f3d5105-79d2-44c5-8e29-1c2f2b357cce",
22
+ "measure_definition_uuid": "1ecf6543-f7ed-4050-bfa3-d3d74d532843",
23
+ "measure_definition_version_uuid": "a4b9b9ec-c704-4bee-a713-d9c6f70888fd",
25
24
  "measure_type": "RubyMeasure",
26
25
  "arguments": [
27
26
  {
@@ -126,21 +125,21 @@
126
125
  "value_type": "double",
127
126
  "variable": true,
128
127
  "variable_type": "RubyContinuousVariable",
129
- "uuid": "7f8d5f81-1791-4360-886c-bcb3084f2494",
130
- "version_uuid": "ece5e402-9fd2-45bd-9811-1ada2d001f40"
128
+ "uuid": "029f1527-429f-4497-908f-ee2e54c22cf3",
129
+ "version_uuid": "040a72b2-e9dd-44d2-9132-8169457ca59b"
131
130
  }
132
131
  ],
133
132
  "workflow_index": 0,
134
133
  "workflow_step_type": "Measure",
135
- "uuid": "2a17e296-f633-43f4-9137-8ede68d3bf59",
136
- "version_uuid": "9df9c6ea-c011-4fab-a51c-eb66bc964ede"
134
+ "uuid": "46121046-5c72-4107-ac9d-7efd833c1db1",
135
+ "version_uuid": "1af389e5-a808-47c3-b733-70f4c33f19a8"
137
136
  },
138
137
  {
139
138
  "measure_definition_class_name": "ExampleMeasureAutoDirectoryName",
140
139
  "measure_definition_directory": "./measures/example_measure_auto_directory_name",
141
140
  "measure_definition_display_name": "ExampleMeasureAutoDirectoryName",
142
- "measure_definition_uuid": "7e82e80e-9754-4749-abb9-ca9fbeb9aecb",
143
- "measure_definition_version_uuid": "a2afd01c-0802-488f-9328-b3b8c5edf2da",
141
+ "measure_definition_uuid": "b7f675a9-b83c-42cc-9838-f266cfdba5c6",
142
+ "measure_definition_version_uuid": "fcbab50e-39a3-41ab-9721-1112589384be",
144
143
  "measure_type": "RubyMeasure",
145
144
  "arguments": [
146
145
  {
@@ -217,21 +216,21 @@
217
216
  "value_type": "double",
218
217
  "variable": true,
219
218
  "variable_type": "RubyContinuousVariable",
220
- "uuid": "2a3b40cf-64df-44ea-8789-6a19238b3d24",
221
- "version_uuid": "a126c981-7e11-4841-9b90-56230a9a1d37"
219
+ "uuid": "d8119872-4827-4370-9081-c25f9cee6bc2",
220
+ "version_uuid": "02bd1fed-86e3-42fb-9a7c-5a9824b97ec0"
222
221
  }
223
222
  ],
224
223
  "workflow_index": 1,
225
224
  "workflow_step_type": "Measure",
226
- "uuid": "4528d12b-9a6f-4d79-9625-b21aff24a9cf",
227
- "version_uuid": "8d8531bc-c3ae-4b29-b537-21dfa20fdc8e"
225
+ "uuid": "a472385e-3ef2-46ab-bc4b-7a046f2f8c0c",
226
+ "version_uuid": "f9cdabed-2483-4cfa-9d2f-0828b8a39902"
228
227
  },
229
228
  {
230
229
  "measure_definition_class_name": "ExampleMeasureAutoDirectoryName",
231
230
  "measure_definition_directory": "./measures/example_measure_auto_directory_name",
232
231
  "measure_definition_display_name": "ExampleMeasureAutoDirectoryName",
233
- "measure_definition_uuid": "a47a285b-1e0d-462b-bc07-c847fc2b24e2",
234
- "measure_definition_version_uuid": "a45d69b7-e315-4fa7-8cf3-3ac28a0c7b9d",
232
+ "measure_definition_uuid": "67f87342-a4fa-49e3-8a10-5bac1ba76864",
233
+ "measure_definition_version_uuid": "7efcd36d-cc25-4512-a116-192dcc8ac467",
235
234
  "measure_type": "RubyMeasure",
236
235
  "arguments": [
237
236
  {
@@ -287,8 +286,8 @@
287
286
  "value_type": "double",
288
287
  "variable": true,
289
288
  "variable_type": "RubyContinuousVariable",
290
- "uuid": "94f55b65-1950-4d9a-96c2-89249cfc0ef7",
291
- "version_uuid": "fa4e204a-6dca-47b3-8506-9ddfca798516"
289
+ "uuid": "e1a9ccb7-37f2-4ac8-a16c-a30181385142",
290
+ "version_uuid": "41ba57dd-1ba9-4bd5-92ed-b061c47ceaa2"
292
291
  },
293
292
  {
294
293
  "argument": {
@@ -332,21 +331,21 @@
332
331
  "value_type": "double",
333
332
  "variable": true,
334
333
  "variable_type": "RubyContinuousVariable",
335
- "uuid": "2de91e1a-4eb3-4b5c-92a6-ddb778f3d5ea",
336
- "version_uuid": "5bb6ccc1-4207-4907-8ab1-a6e0f61643db"
334
+ "uuid": "aa86a9d4-e41f-4444-991b-718849d3c000",
335
+ "version_uuid": "8767f37e-1c02-4371-9e6f-3e63ed4f3962"
337
336
  }
338
337
  ],
339
338
  "workflow_index": 2,
340
339
  "workflow_step_type": "Measure",
341
- "uuid": "47f7db54-0df3-4e2e-b34d-8fc50e4f7c9a",
342
- "version_uuid": "20671249-56c2-4af9-9271-5a32b50dc3d4"
340
+ "uuid": "f1538361-06ed-4b57-9f93-d32d3970ddfe",
341
+ "version_uuid": "f23d0f4b-4d59-403d-a3ad-7776f044347d"
343
342
  },
344
343
  {
345
344
  "measure_definition_class_name": "ExampleMeasureAutoDirectoryName",
346
345
  "measure_definition_directory": "./measures/example_measure_auto_directory_name",
347
346
  "measure_definition_display_name": "ExampleMeasureAutoDirectoryName",
348
- "measure_definition_uuid": "49045d84-57be-4589-9c55-766b6665a92f",
349
- "measure_definition_version_uuid": "52e753ac-d357-4e1d-8fad-8b2748f8f599",
347
+ "measure_definition_uuid": "43396da4-1d00-46da-a178-64e953641eb7",
348
+ "measure_definition_version_uuid": "ed15f139-9d8f-46eb-a2bf-74bb911f04fc",
350
349
  "measure_type": "RubyMeasure",
351
350
  "arguments": [
352
351
  {
@@ -416,21 +415,21 @@
416
415
  "value_type": "double",
417
416
  "variable": true,
418
417
  "variable_type": "RubyContinuousVariable",
419
- "uuid": "655ad7a0-f830-41a2-a706-f67e2d1c673c",
420
- "version_uuid": "4037db56-3e59-42a9-ade9-2b470f3249f4"
418
+ "uuid": "b810467d-8fa3-4c8b-926e-2b1932e32564",
419
+ "version_uuid": "1aeeeb6a-8299-4299-9f62-2e2de4b456b4"
421
420
  }
422
421
  ],
423
422
  "workflow_index": 3,
424
423
  "workflow_step_type": "Measure",
425
- "uuid": "3c079991-7c3a-41f0-98ec-07c62b800cd1",
426
- "version_uuid": "f038a7d6-933f-48aa-b825-61d8212f882d"
424
+ "uuid": "11328147-211a-4273-8af6-fa5f9b0cb887",
425
+ "version_uuid": "e93d77a4-aff7-410c-960b-be984f5e46f4"
427
426
  },
428
427
  {
429
428
  "measure_definition_class_name": "ExampleMeasureAutoDirectoryName",
430
429
  "measure_definition_directory": "./measures/example_measure_auto_directory_name",
431
430
  "measure_definition_display_name": "ExampleMeasureAutoDirectoryName",
432
- "measure_definition_uuid": "fc0ddf03-c967-43dc-b3e7-923a52e334d8",
433
- "measure_definition_version_uuid": "7dc18acb-0c61-4eed-bc18-5ef646673bb1",
431
+ "measure_definition_uuid": "f7146d2a-bff6-41bf-8b86-e8cb43348117",
432
+ "measure_definition_version_uuid": "07973dae-0aba-49a8-81ae-1a2181f5c54f",
434
433
  "measure_type": "RubyMeasure",
435
434
  "arguments": [
436
435
  {
@@ -500,21 +499,21 @@
500
499
  "value_type": "double",
501
500
  "variable": true,
502
501
  "variable_type": "RubyContinuousVariable",
503
- "uuid": "41645bf5-f9d6-4959-8025-940b06cdefa4",
504
- "version_uuid": "ef3215b3-31ed-4e49-9753-ca98975b5f63"
502
+ "uuid": "b5ee236a-584a-45b0-b8be-40c92d8ba7a4",
503
+ "version_uuid": "8cc4205e-b2bf-4f2d-9db0-566b8da625b8"
505
504
  }
506
505
  ],
507
506
  "workflow_index": 4,
508
507
  "workflow_step_type": "Measure",
509
- "uuid": "be5fd0d0-43d5-44fe-bd57-47ba1802fb84",
510
- "version_uuid": "91cc8ea6-a868-4418-8809-8853aa53ab31"
508
+ "uuid": "8390d255-adce-40cc-85cf-d348ac0dba5d",
509
+ "version_uuid": "d5d237dc-fd5d-466d-927a-5edbec31679e"
511
510
  },
512
511
  {
513
512
  "measure_definition_class_name": "ExampleMeasureAutoDirectoryName",
514
513
  "measure_definition_directory": "./measures/example_measure_auto_directory_name",
515
514
  "measure_definition_display_name": "ExampleMeasureAutoDirectoryName",
516
- "measure_definition_uuid": "0ef454d1-7e5f-46b9-8b38-5756faf0161a",
517
- "measure_definition_version_uuid": "fff1a9a0-85ab-4653-99be-0e36341bfd42",
515
+ "measure_definition_uuid": "cbf19773-ce7f-48cc-a5d1-638c15033689",
516
+ "measure_definition_version_uuid": "cd6e0064-ca8c-4d71-a4fb-56fc243bc849",
518
517
  "measure_type": "RubyMeasure",
519
518
  "arguments": [
520
519
  {
@@ -570,14 +569,14 @@
570
569
  "value_type": "double",
571
570
  "variable": true,
572
571
  "variable_type": "RubyContinuousVariable",
573
- "uuid": "3a8d1266-a394-48ca-8f03-1be11afdc761",
574
- "version_uuid": "d2e290af-824c-4f69-bc60-37187f28e8fc"
572
+ "uuid": "220b0c95-28c9-420a-8fc6-4d00ccab8dd0",
573
+ "version_uuid": "e59ae1bd-b7e9-4295-8246-e6426f038119"
575
574
  }
576
575
  ],
577
576
  "workflow_index": 5,
578
577
  "workflow_step_type": "Measure",
579
- "uuid": "d989b8d4-5083-4ac9-94f2-f58f674c3c85",
580
- "version_uuid": "28184cba-00db-4442-94aa-42db19bf5146"
578
+ "uuid": "d68a5231-f9d6-40fd-b901-25eac3864e21",
579
+ "version_uuid": "8fd5ffac-6cb4-4023-b60b-a18b0300a6c8"
581
580
  }
582
581
  ],
583
582
  "analysis_type": "lhs"
@@ -0,0 +1,23 @@
1
+ {
2
+ "analysis": {
3
+ "display_name": "workflow",
4
+ "name": "workflow",
5
+ "output_variables": [
6
+
7
+ ],
8
+ "problem": {
9
+ "analysis_type": null,
10
+ "algorithm": {
11
+ "objective_functions": [
12
+
13
+ ]
14
+ },
15
+ "workflow": [
16
+
17
+ ]
18
+ },
19
+ "seed": null,
20
+ "weather_file": null,
21
+ "file_format_version": 1
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "classname": "RotateBuilding",
3
+ "name": "rotate_building",
4
+ "display_name": "Rotate Building",
5
+ "measure_type": "RubyMeasure",
6
+ "arguments": [
7
+ {
8
+ "local_variable": "relative_building_rotation",
9
+ "variable_type": "Double",
10
+ "name": "relative_building_rotation",
11
+ "display_name": "Number of Degrees to Rotate Building",
12
+ "units": "positive value is clockwise",
13
+ "description": null,
14
+ "default_value": 90.0
15
+ }
16
+ ],
17
+ "name_xml": "Rotate Building Relative to Current Orientation",
18
+ "uid": "a5be6c96-4ecc-47fa-8d32-f4216ebc2e7d",
19
+ "version_id": "aeb20d61-b773-4d20-a2ef-fe948cdc2858",
20
+ "modeler_description": "Get the North Axis field for the OS:Building object and adjusted it based on the user specified value. If the starting value is 20 degrees and the user value is 5 degrees, then the resulting value is 25 degrees.",
21
+ "description": "Rotate your building relative to its current orientation. This will not rotate site shading objects.",
22
+ "tags": [
23
+ "Envelope.Form"
24
+ ]
25
+ }
@@ -0,0 +1,80 @@
1
+ #start the measure
2
+ class RotateBuilding < OpenStudio::Ruleset::ModelUserScript
3
+
4
+ #define the name that a user will see
5
+ def name
6
+ return "Rotate Building"
7
+ end
8
+
9
+ #define the arguments that the user will input
10
+ def arguments(model)
11
+ args = OpenStudio::Ruleset::OSArgumentVector.new
12
+
13
+ #make an argument for your name
14
+ relative_building_rotation = OpenStudio::Ruleset::OSArgument::makeDoubleArgument("relative_building_rotation",true)
15
+ relative_building_rotation.setDisplayName("Number of Degrees to Rotate Building (positive value is clockwise).")
16
+ relative_building_rotation.setDefaultValue(90.0)
17
+ args << relative_building_rotation
18
+
19
+ return args
20
+ end #end the arguments method
21
+
22
+ #define what happens when the measure is run
23
+ def run(model, runner, user_arguments)
24
+ super(model, runner, user_arguments)
25
+
26
+ #use the built-in error checking
27
+ if not runner.validateUserArguments(arguments(model), user_arguments)
28
+ return false
29
+ end
30
+
31
+ #assign the user inputs to variables
32
+ relative_building_rotation = runner.getDoubleArgumentValue("relative_building_rotation",user_arguments)
33
+
34
+ #check the relative_building_rotation for reasonableness
35
+ if relative_building_rotation > 360 or relative_building_rotation < -360
36
+ relative_building_rotation = relative_building_rotation -360.0*(relative_building_rotation/360.0).truncate
37
+ runner.registerWarning("Requested rotation was not between -360 and 360. Effective relative rotation is #{relative_building_rotation} degrees.")
38
+ end
39
+
40
+ #reporting initial condition of model
41
+ building = model.getBuilding
42
+ runner.registerValue("orientation_initial",building.northAxis)
43
+ runner.registerInitialCondition("The building's initial rotation was #{building.northAxis} degrees.")
44
+
45
+ #report as not applicable if effective relative rotation is 0
46
+ if relative_building_rotation == 0
47
+ runner.registerAsNotApplicable("The requested rotation was 0 degrees. The model was not altered.")
48
+ else
49
+ #rotate the building
50
+ final_building_angle = building.setNorthAxis(building.northAxis + relative_building_rotation)
51
+ runner.registerInfo("The building has been rotated by #{relative_building_rotation} degrees.")
52
+ end
53
+
54
+ #check for site shading
55
+ model_contains_site_shading = false
56
+ shading_surface_groups = model.getShadingSurfaceGroups
57
+ shading_surface_groups.each do |shading_surface_group|
58
+ if shading_surface_group.shadingSurfaceType == "Site"
59
+ model_contains_site_shading = true
60
+ end
61
+ end
62
+
63
+ #issue warning if site shading surfaces exist
64
+ if model_contains_site_shading
65
+ runner.registerWarning("The model contains one or more site shading groups. They were not rotated with the building.")
66
+ end
67
+
68
+ #reporting final condition of model
69
+ runner.registerValue("orientation_final",building.northAxis)
70
+ runner.registerFinalCondition("The building's final rotation is #{building.northAxis} degrees.")
71
+
72
+ return true
73
+
74
+ end #end the run method
75
+
76
+
77
+ end #end the measure
78
+
79
+ #this allows the measure to be used by the application
80
+ RotateBuilding.new.registerWithApplication
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <measure xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://bcl.nrel.gov/xsd/measures/version/1.0.xsd"><name>Rotate Building Relative to Current Orientation</name><uid>a5be6c96-4ecc-47fa-8d32-f4216ebc2e7d</uid><version_id>aeb20d61-b773-4d20-a2ef-fe948cdc2858</version_id><description>Rotate your building relative to its current orientation. This will not rotate site shading objects.</description><modeler_description>Get the North Axis field for the OS:Building object and adjusted it based on the user specified value. If the starting value is 20 degrees and the user value is 5 degrees, then the resulting value is 25 degrees.</modeler_description><tags><tag>Envelope.Form</tag></tags><attributes><attribute><name>Measure Type</name><value>ModelMeasure</value><datatype>string</datatype></attribute><attribute><name>Measure Function</name><value>Measure</value><datatype>string</datatype></attribute><attribute><name>Requires EnergyPlus Results</name><value>false</value><datatype>boolean</datatype></attribute><attribute><name>Uses SketchUp API</name><value>false</value><datatype>boolean</datatype></attribute></attributes><files><file><filename>RotateBuilding_TestModel_01.osm</filename><filetype>osm</filetype><usage_type>test</usage_type><checksum>E5C7E0B6</checksum></file><file><filename>RotateBuilding_Test.rb</filename><filetype>rb</filetype><usage_type>test</usage_type><checksum>D9410036</checksum></file><file><version><software_program>OpenStudio</software_program><identifier>1.3.0</identifier></version><filename>measure.rb</filename><filetype>rb</filetype><usage_type>script</usage_type><checksum>FEC15373</checksum></file></files></measure>
@@ -0,0 +1,63 @@
1
+ {
2
+ "classname": "SetThermostatSchedules",
3
+ "name": "set_thermostat_schedules",
4
+ "display_name": "Set Thermostat Schedules",
5
+ "measure_type": "RubyMeasure",
6
+ "arguments": [
7
+ {
8
+ "local_variable": "zones",
9
+ "variable_type": "Choice",
10
+ "name": "zones",
11
+ "display_name": "Choose Thermal Zones to change thermostat schedules on",
12
+ "units": null,
13
+ "description": null,
14
+ "default_value": "*All Thermal Zones*",
15
+ "choices": [
16
+ "*All Thermal Zones*"
17
+ ]
18
+ },
19
+ {
20
+ "local_variable": "cooling_sch",
21
+ "variable_type": "Choice",
22
+ "name": "cooling_sch",
23
+ "display_name": "Choose Cooling Schedule",
24
+ "units": null,
25
+ "description": null,
26
+ "default_value": "*No Change*",
27
+ "choices": [
28
+ "",
29
+ "*No Change*"
30
+ ]
31
+ },
32
+ {
33
+ "local_variable": "heating_sch",
34
+ "variable_type": "Choice",
35
+ "name": "heating_sch",
36
+ "display_name": "Choose Heating Schedule",
37
+ "units": null,
38
+ "description": null,
39
+ "default_value": "*No Change*",
40
+ "choices": [
41
+ "",
42
+ "*No Change*"
43
+ ]
44
+ },
45
+ {
46
+ "local_variable": "material_cost",
47
+ "variable_type": "Double",
48
+ "name": "material_cost",
49
+ "display_name": "Material and Installation Costs per Thermal Zone",
50
+ "units": "$/thermal zone",
51
+ "description": null,
52
+ "default_value": 0.0
53
+ }
54
+ ],
55
+ "name_xml": "Set Thermostat Schedules",
56
+ "uid": "d241d623-d596-4b26-9b67-fe390be1e839",
57
+ "version_id": "699b90d0-1b73-4208-869a-c6987afda0da",
58
+ "modeler_description": "Sets zone thermostat schedules to schedules in the same file. If a zone does not have a thermostat this measure will add one.",
59
+ "description": "Sets zone thermostat schedules to schedules in the same file. If a zone does not have a thermostat this measure will add one",
60
+ "tags": [
61
+ "HVAC.HVAC Controls"
62
+ ]
63
+ }
@@ -0,0 +1,254 @@
1
+ #see the URL below for information on how to write OpenStuido measures
2
+ # http://openstudio.nrel.gov/openstudio-measure-writing-guide
3
+
4
+ #start the measure
5
+ class SetThermostatSchedules < OpenStudio::Ruleset::ModelUserScript
6
+
7
+ #define the name that a user will see, this method may be deprecated as
8
+ #the display name in PAT comes from the name field in measure.xml
9
+ def name
10
+ return "Set Thermostat Schedules"
11
+ end
12
+
13
+ #define the arguments that the user will input
14
+ def arguments(model)
15
+ args = OpenStudio::Ruleset::OSArgumentVector.new
16
+
17
+ #populate choice argument for thermal zones in the model
18
+ zone_handles = OpenStudio::StringVector.new
19
+ zone_display_names = OpenStudio::StringVector.new
20
+
21
+ #putting zone names into hash
22
+ zone_hash = {}
23
+ model.getThermalZones.each do |zone|
24
+ zone_hash[zone.name.to_s] = zone
25
+ end
26
+
27
+ #looping through sorted hash of zones
28
+ zone_hash.sort.map do |zone_name, zone|
29
+ if zone.thermostatSetpointDualSetpoint.is_initialized
30
+ zone_handles << zone.handle.to_s
31
+ zone_display_names << zone_name
32
+ end
33
+ end
34
+
35
+ #add building to string vector with zones
36
+ building = model.getBuilding
37
+ zone_handles << building.handle.to_s
38
+ zone_display_names << "*All Thermal Zones*"
39
+
40
+ #make an argument for zones
41
+ zones = OpenStudio::Ruleset::OSArgument::makeChoiceArgument("zones", zone_handles, zone_display_names, true)
42
+ zones.setDisplayName("Choose Thermal Zones to change thermostat schedules on.")
43
+ zones.setDefaultValue("*All Thermal Zones*") #if no zone is chosen this will run on all zones
44
+ args << zones
45
+
46
+ #populate choice argument for schedules in the model
47
+ sch_handles = OpenStudio::StringVector.new
48
+ sch_display_names = OpenStudio::StringVector.new
49
+
50
+ #putting schedule names into hash
51
+ sch_hash = {}
52
+ model.getSchedules.each do |sch|
53
+ sch_hash[sch.name.to_s] = sch
54
+ end
55
+
56
+ #looping through sorted hash of schedules
57
+ sch_hash.sort.map do |sch_name, sch|
58
+ if not sch.scheduleTypeLimits.empty?
59
+ unitType = sch.scheduleTypeLimits.get.unitType
60
+ #puts "#{sch.name}, #{unitType}"
61
+ if unitType == "Temperature"
62
+ sch_handles << sch.handle.to_s
63
+ sch_display_names << sch_name
64
+ end
65
+ end
66
+ end
67
+
68
+ #add empty handle to string vector with schedules
69
+ sch_handles << OpenStudio::toUUID("").to_s
70
+ sch_display_names << "*No Change*"
71
+
72
+ #make an argument for cooling schedule
73
+ cooling_sch = OpenStudio::Ruleset::OSArgument::makeChoiceArgument("cooling_sch", sch_handles, sch_display_names, true)
74
+ cooling_sch.setDisplayName("Choose Cooling Schedule.")
75
+ cooling_sch.setDefaultValue("*No Change*") #if no change is chosen then cooling schedules will not be changed
76
+ args << cooling_sch
77
+
78
+ #make an argument for heating schedule
79
+ heating_sch = OpenStudio::Ruleset::OSArgument::makeChoiceArgument("heating_sch", sch_handles, sch_display_names, true)
80
+ heating_sch.setDisplayName("Choose Heating Schedule.")
81
+ heating_sch.setDefaultValue("*No Change*") #if no change is chosen then heating schedules will not be changed
82
+ args << heating_sch
83
+
84
+ #make an argument for material and installation cost
85
+ material_cost = OpenStudio::Ruleset::OSArgument::makeDoubleArgument("material_cost",true)
86
+ material_cost.setDisplayName("Material and Installation Costs per Thermal Zone ($/thermal zone).")
87
+ material_cost.setDefaultValue(0.0)
88
+ args << material_cost
89
+
90
+ return args
91
+ end #end the arguments method
92
+
93
+ #define what happens when the measure is run
94
+ def run(model, runner, user_arguments)
95
+ super(model, runner, user_arguments)
96
+
97
+ #use the built-in error checking
98
+ if not runner.validateUserArguments(arguments(model), user_arguments)
99
+ return false
100
+ end
101
+
102
+ #assign the user inputs to variables
103
+ zones = runner.getOptionalWorkspaceObjectChoiceValue("zones",user_arguments,model) #model is passed in because of argument type
104
+ cooling_sch = runner.getOptionalWorkspaceObjectChoiceValue("cooling_sch",user_arguments,model) #model is passed in because of argument type
105
+ heating_sch = runner.getOptionalWorkspaceObjectChoiceValue("heating_sch",user_arguments,model) #model is passed in because of argument type
106
+ material_cost = runner.getDoubleArgumentValue("material_cost",user_arguments)
107
+
108
+ #check the zone selection for reasonableness
109
+ apply_to_all_zones = false
110
+ selected_zone = nil
111
+ if zones.empty?
112
+ handle = runner.getStringArgumentValue("zones",user_arguments)
113
+ if handle.empty?
114
+ runner.registerError("No thermal zone was chosen.")
115
+ return false
116
+ else
117
+ runner.registerError("The selected thermal zone with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
118
+ return false
119
+ end
120
+ else
121
+ if not zones.get.to_ThermalZone.empty?
122
+ selected_zone = zones.get.to_ThermalZone.get
123
+ elsif not zones.get.to_Building.empty?
124
+ apply_to_all_zones = true
125
+ else
126
+ runner.registerError("Script Error - argument not showing up as thermal zone.")
127
+ return false
128
+ end
129
+ end #end of if zones.empty?
130
+
131
+ #depending on user input, add selected zones to an array
132
+ selected_zones = []
133
+ if apply_to_all_zones == true
134
+ selected_zones = model.getThermalZones
135
+ else
136
+ selected_zones << selected_zone
137
+ end
138
+
139
+ #check the cooling_sch for reasonableness
140
+ if cooling_sch.empty?
141
+ handle = runner.getStringArgumentValue("cooling_sch",user_arguments)
142
+ if handle == OpenStudio::toUUID("").to_s
143
+ # no change
144
+ cooling_sch = nil
145
+ else
146
+ runner.registerError("The selected schedule with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
147
+ return false
148
+ end
149
+ else
150
+ if not cooling_sch.get.to_Schedule.empty?
151
+ cooling_sch = cooling_sch.get.to_Schedule.get
152
+ else
153
+ runner.registerError("Script Error - argument not showing up as schedule.")
154
+ return false
155
+ end
156
+ end #end of if cooling_sch.empty?
157
+
158
+ #check the heating_sch for reasonableness
159
+ if heating_sch.empty?
160
+ handle = runner.getStringArgumentValue("heating_sch",user_arguments)
161
+ if handle == OpenStudio::toUUID("").to_s
162
+ # no change
163
+ heating_sch = nil
164
+ else
165
+ runner.registerError("The selected schedule with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
166
+ return false
167
+ end
168
+ else
169
+ if not heating_sch.get.to_Schedule.empty?
170
+ heating_sch = heating_sch.get.to_Schedule.get
171
+ else
172
+ runner.registerError("Script Error - argument not showing up as schedule.")
173
+ return false
174
+ end
175
+ end #end of if heating_sch.empty?
176
+
177
+ number_zones_modified = 0
178
+ total_cost = 0
179
+ if heating_sch or cooling_sch
180
+
181
+ selected_zones.each do |zone|
182
+
183
+ thermostatSetpointDualSetpoint = zone.thermostatSetpointDualSetpoint
184
+ if thermostatSetpointDualSetpoint.empty?
185
+ runner.registerInfo("Creating thermostat for thermal zone '#{zone.name}'.")
186
+
187
+ thermostatSetpointDualSetpoint = OpenStudio::Model::ThermostatSetpointDualSetpoint.new(model)
188
+ zone.setThermostatSetpointDualSetpoint(thermostatSetpointDualSetpoint)
189
+ else
190
+ thermostatSetpointDualSetpoint = thermostatSetpointDualSetpoint.get
191
+
192
+ # make sure this thermostat is unique to this zone
193
+ if thermostatSetpointDualSetpoint.getSources("OS_ThermalZone".to_IddObjectType).size > 1
194
+ # if not create a new copy
195
+ runner.registerInfo("Copying thermostat for thermal zone '#{zone.name}'.")
196
+
197
+ oldThermostat = thermostatSetpointDualSetpoint
198
+ thermostatSetpointDualSetpoint = OpenStudio::Model::ThermostatSetpointDualSetpoint.new(model)
199
+ if not oldThermostat.heatingSetpointTemperatureSchedule.empty?
200
+ thermostatSetpointDualSetpoint.setHeatingSetpointTemperatureSchedule(oldThermostat.heatingSetpointTemperatureSchedule.get)
201
+ end
202
+ if not oldThermostat.coolingSetpointTemperatureSchedule.empty?
203
+ thermostatSetpointDualSetpoint.setCoolingSetpointTemperatureSchedule(oldThermostat.coolingSetpointTemperatureSchedule.get)
204
+ end
205
+ zone.setThermostatSetpointDualSetpoint(thermostatSetpointDualSetpoint)
206
+ end
207
+ end
208
+
209
+ if heating_sch
210
+ if not thermostatSetpointDualSetpoint.setHeatingSetpointTemperatureSchedule(heating_sch)
211
+ runner.registerError("Script Error - cannot set heating schedule for thermal zone '#{zone.name}'.")
212
+ return false
213
+ end
214
+ end
215
+
216
+ if cooling_sch
217
+ if not thermostatSetpointDualSetpoint.setCoolingSetpointTemperatureSchedule(cooling_sch)
218
+ runner.registerError("Script Error - cannot set cooling schedule for thermal zone '#{zone.name}'.")
219
+ return false
220
+ end
221
+ end
222
+
223
+ if material_cost.abs != 0
224
+ total_cost += material_cost
225
+ OpenStudio::Model::LifeCycleCost::createLifeCycleCost("LCC_Mat - #{zone.name} Thermostats", zone, material_cost, "CostPerEach", "Construction")
226
+ end
227
+
228
+ number_zones_modified += 1
229
+ end
230
+ end
231
+
232
+ runner.registerFinalCondition("Replaced thermostats for #{number_zones_modified} thermal zones, capital cost #{total_cost}")
233
+
234
+ if number_zones_modified == 0
235
+ runner.registerAsNotApplicable("No thermostats altered")
236
+ end
237
+
238
+ return true
239
+
240
+ end #end the run method
241
+
242
+ end #end the measure
243
+
244
+ #this allows the measure to be use by the application
245
+ SetThermostatSchedules.new.registerWithApplication
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <measure xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://bcl.nrel.gov/xsd/measures/version/1.0.xsd"><name>Set Thermostat Schedules</name><uid>d241d623-d596-4b26-9b67-fe390be1e839</uid><version_id>699b90d0-1b73-4208-869a-c6987afda0da</version_id><description>Sets zone thermostat schedules to schedules in the same file. If a zone does not have a thermostat this measure will add one</description><modeler_description>Sets zone thermostat schedules to schedules in the same file. If a zone does not have a thermostat this measure will add one.</modeler_description><tags><tag>HVAC.HVAC Controls</tag></tags><attributes><attribute><name>Measure Function</name><value>Measure</value><datatype>string</datatype></attribute><attribute><name>Requires EnergyPlus Results</name><value>false</value><datatype>boolean</datatype></attribute><attribute><name>Measure Type</name><value>ModelMeasure</value><datatype>string</datatype></attribute><attribute><name>Uses SketchUp API</name><value>false</value><datatype>boolean</datatype></attribute></attributes><files><file><filename>SetThermostatSchedules_Test.rb</filename><filetype>rb</filetype><usage_type>test</usage_type><checksum>215A22F5</checksum></file><file><version><software_program>OpenStudio</software_program><identifier>1.2.0</identifier></version><filename>measure.rb</filename><filetype>rb</filetype><usage_type>script</usage_type><checksum>764BA2C0</checksum></file></files></measure>