openstudio-analysis 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>