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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -6
- data/README.md +55 -7
- data/Rakefile +10 -0
- data/lib/openstudio/analysis/algorithm_attributes.rb +22 -0
- data/lib/openstudio/analysis/formulation.rb +174 -0
- data/lib/openstudio/analysis/translator/excel.rb +65 -48
- data/lib/openstudio/analysis/version.rb +1 -1
- data/lib/openstudio/analysis/workflow.rb +197 -0
- data/lib/openstudio/analysis/workflow_step.rb +312 -0
- data/lib/openstudio/analysis.rb +8 -0
- data/lib/openstudio/helpers/string.rb +22 -22
- data/lib/openstudio/templates/analysis.json.erb +0 -1
- data/lib/openstudio-analysis.rb +9 -0
- data/spec/files/0_1_09_small_list_incomplete.xlsx +0 -0
- data/spec/files/0_2_0_template_simpletest.xlsx +0 -0
- data/spec/files/0_4_0_lhs_discrete_continuous.xlsx +0 -0
- data/spec/files/analysis/example_analysis_api.json +656 -0
- data/spec/files/analysis/examples/discrete_lhs_example.json +809 -0
- data/spec/files/analysis/examples/medium_office_example.json +1673 -0
- data/spec/files/analysis/lhs_discrete_and_continuous_variables_api.json +1230 -0
- data/spec/files/analysis/medium_office.json +91 -92
- data/spec/files/analysis/medium_office.zip +0 -0
- data/spec/files/analysis/name_goes_here_api.json +1681 -0
- data/spec/files/analysis/output_vars_api.json +632 -0
- data/spec/files/analysis/preflight_api.json +1518 -0
- data/spec/files/analysis/simple_test_api.json +519 -0
- data/spec/files/analysis/test_model_api.json +493 -0
- data/spec/files/export/analysis/0_1_09_outputvars.json +38 -39
- data/spec/files/export/analysis/0_1_09_outputvars.zip +0 -0
- data/spec/files/export/analysis/0_1_11_discrete_variables.json +46 -47
- data/spec/files/export/analysis/0_1_11_discrete_variables.zip +0 -0
- data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.json +8 -9
- data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.zip +0 -0
- data/spec/files/export/analysis/0_2_0_template_simpletest.json +19 -14
- data/spec/files/export/analysis/0_2_0_template_simpletest.zip +0 -0
- data/spec/files/export/analysis/0_3_0_outputs.json +99 -100
- data/spec/files/export/analysis/0_3_0_outputs.zip +0 -0
- data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.json → 276ccf51-ed22-4604-a380-8985cec5efe8.json} +103 -104
- data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.zip → 276ccf51-ed22-4604-a380-8985cec5efe8.zip} +0 -0
- data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.json → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.json} +107 -108
- data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.zip → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.zip} +0 -0
- data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.json → 9560f95b-5730-4038-a95b-328c825c596b.json} +99 -100
- data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.zip → 9560f95b-5730-4038-a95b-328c825c596b.zip} +0 -0
- data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.json → c50f0062-cdfb-4dec-bc02-215f6c29af3c.json} +107 -108
- data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.zip → c50f0062-cdfb-4dec-bc02-215f6c29af3c.zip} +0 -0
- data/spec/files/export/analysis/discrete_lhs_example.json +1185 -0
- data/spec/files/export/analysis/discrete_lhs_example.zip +0 -0
- data/spec/files/export/analysis/small_seed.json +38 -39
- data/spec/files/export/analysis/small_seed.zip +0 -0
- data/spec/files/export/workflow/analysis.json +23 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.json +25 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.rb +80 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.xml +2 -0
- data/spec/files/measures/SetThermostatSchedules/measure.json +63 -0
- data/spec/files/measures/SetThermostatSchedules/measure.rb +254 -0
- data/spec/files/measures/SetThermostatSchedules/measure.xml +2 -0
- data/spec/openstudio/excel_spec.rb +11 -11
- data/spec/openstudio/formulation_spec.rb +107 -0
- data/spec/openstudio/workflow_spec.rb +90 -0
- data/spec/openstudio/workflow_step_spec.rb +116 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Formulation.xml +28 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-object-instance.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.xml +1 -1
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.xml +30 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.xml +11 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.xml +6 -6
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.xml +52 -8
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.xml +22 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.xml +28 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.xml +3 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.xml +13 -6
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.xml +55 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-dynamic-uuid-assignments.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-measure-existence-checks.xml +8 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-objective-functions.xml +13 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-3-and-short-display-names.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-5-and-measure-paths.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.0.xml +40 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.xml +1 -1
- data/spec/reports/SPEC-OpenStudio-Analysis-Workflow.xml +31 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-WorkflowStep.xml +29 -0
- data/spec/spec_helper.rb +1 -1
- metadata +87 -18
|
Binary file
|
|
@@ -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": "
|
|
24
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
130
|
-
"version_uuid": "
|
|
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": "
|
|
136
|
-
"version_uuid": "
|
|
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": "
|
|
143
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
221
|
-
"version_uuid": "
|
|
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": "
|
|
227
|
-
"version_uuid": "
|
|
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": "
|
|
234
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
291
|
-
"version_uuid": "
|
|
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": "
|
|
336
|
-
"version_uuid": "
|
|
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": "
|
|
342
|
-
"version_uuid": "
|
|
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": "
|
|
349
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
420
|
-
"version_uuid": "
|
|
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": "
|
|
426
|
-
"version_uuid": "
|
|
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": "
|
|
433
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
504
|
-
"version_uuid": "
|
|
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": "
|
|
510
|
-
"version_uuid": "
|
|
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": "
|
|
517
|
-
"measure_definition_version_uuid": "
|
|
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": "
|
|
574
|
-
"version_uuid": "
|
|
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": "
|
|
580
|
-
"version_uuid": "
|
|
578
|
+
"uuid": "d68a5231-f9d6-40fd-b901-25eac3864e21",
|
|
579
|
+
"version_uuid": "8fd5ffac-6cb4-4023-b60b-a18b0300a6c8"
|
|
581
580
|
}
|
|
582
581
|
],
|
|
583
582
|
"analysis_type": "lhs"
|
|
Binary file
|
|
@@ -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>
|