openstudio-common-measures 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/README.md +7 -2
  4. data/doc_templates/copyright_erb.txt +1 -1
  5. data/lib/measures/AddCostPerFloorAreaUnusedToLights/measure.xml +2 -8
  6. data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/measure.xml +9 -3
  7. data/lib/measures/AddSimplePvToShadingSurfacesByType/measure.xml +2 -2
  8. data/lib/measures/RemoveUnusedDefaultProfiles/measure.xml +2 -2
  9. data/lib/measures/ReportModelChanges/measure.xml +2 -2
  10. data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/measure.xml +4 -4
  11. data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/measure.xml +4 -4
  12. data/lib/measures/SetGasBurnerEfficiency/measure.xml +4 -4
  13. data/lib/measures/ShiftScheduleProfileTime/measure.xml +4 -4
  14. data/lib/measures/SwapLightsDefinition/measure.xml +3 -5
  15. data/lib/measures/add_ems_emissions_reporting/measure.rb +236 -29
  16. data/lib/measures/add_ems_emissions_reporting/measure.xml +362 -10
  17. data/lib/measures/add_ev_load/measure.rb +51 -8
  18. data/lib/measures/add_ev_load/measure.xml +23 -5
  19. data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +3 -3
  20. data/lib/measures/envelope_and_internal_load_breakdown/resources/report.html.erb +5 -1
  21. data/lib/measures/example_report/measure.xml +3 -3
  22. data/lib/measures/example_report/resources/report.html.erb +5 -1
  23. data/lib/measures/generic_qaqc/README.md +19 -4
  24. data/lib/measures/generic_qaqc/README.md.erb +7 -1
  25. data/lib/measures/generic_qaqc/docs/generic_qaqc_detailed.jpg +0 -0
  26. data/lib/measures/generic_qaqc/docs/generic_qaqc_summary.jpg +0 -0
  27. data/lib/measures/generic_qaqc/measure.rb +34 -29
  28. data/lib/measures/generic_qaqc/measure.xml +181 -82
  29. data/lib/measures/generic_qaqc/resources/check_cond_zns.rb +3 -1
  30. data/lib/measures/generic_qaqc/resources/check_domestic_hot_water.rb +13 -8
  31. data/lib/measures/generic_qaqc/resources/check_envelope_conductance.rb +330 -231
  32. data/lib/measures/generic_qaqc/resources/check_eui_by_end_use.rb +59 -20
  33. data/lib/measures/generic_qaqc/resources/check_eui_reasonableness.rb +58 -20
  34. data/lib/measures/generic_qaqc/resources/check_internal_loads.rb +57 -56
  35. data/lib/measures/generic_qaqc/resources/check_mech_sys_capacity.rb +4 -1
  36. data/lib/measures/generic_qaqc/resources/check_mech_sys_efficiency.rb +27 -22
  37. data/lib/measures/generic_qaqc/resources/check_mech_sys_part_load_eff.rb +4 -1
  38. data/lib/measures/generic_qaqc/resources/check_mech_sys_type.rb +3 -3
  39. data/lib/measures/generic_qaqc/resources/check_schedules.rb +65 -101
  40. data/lib/measures/generic_qaqc/resources/check_simultaneous_heating_and_cooling.rb +3 -1
  41. data/lib/measures/generic_qaqc/resources/check_supply_air_and_thermostat_temp_difference.rb +3 -1
  42. data/lib/measures/generic_qaqc/resources/os_lib_reporting_qaqc.rb +49 -15
  43. data/lib/measures/generic_qaqc/resources/report.html.erb +5 -1
  44. data/lib/measures/hvac_psychrometric_chart/measure.xml +3 -3
  45. data/lib/measures/hvac_psychrometric_chart/resources/report.html.erb +5 -1
  46. data/lib/measures/openstudio_results/measure.xml +3 -3
  47. data/lib/measures/openstudio_results/resources/report.html.erb +5 -1
  48. data/lib/measures/set_run_period/measure.xml +2 -2
  49. data/lib/measures/view_data/measure.xml +4 -4
  50. data/lib/measures/view_data/resources/report.html.in +189 -19
  51. data/lib/measures/view_data/resources/va3c.rb +1 -0
  52. data/lib/measures/view_model/measure.xml +9 -9
  53. data/lib/measures/view_model/resources/report.html.in +189 -19
  54. data/lib/measures/view_model/resources/va3c.rb +1 -0
  55. data/lib/openstudio/common_measures/version.rb +1 -1
  56. data/openstudio-common-measures.gemspec +1 -1
  57. metadata +7 -5
@@ -1845,7 +1845,7 @@ var os_data;
1845
1845
  var os_data_const = <%=os_data %>;
1846
1846
  // END_REMOVE
1847
1847
 
1848
- var renderer, scene, light, scene_objects, scene_edges, object_edges, coincident_objects, back_objects;
1848
+ var renderer, scene, light, scene_objects, scene_edges, object_edges, coincident_objects, back_objects, dot_points;
1849
1849
  var perspectiveCamera, orthographicCamera, perspectiveControls, orthographicControls;
1850
1850
  var project, materials, variable;
1851
1851
  var dataFolder, dateTimeControl;
@@ -1857,7 +1857,7 @@ var raycaster;
1857
1857
  var mouse;
1858
1858
  var headsUp;
1859
1859
  var intersected = [];
1860
- var selected_material, unknown_material;
1860
+ var selected_material, unknown_material, dot_material;
1861
1861
 
1862
1862
  var getStringFromLocalStorage = function (key, defaultValue) {
1863
1863
  try {
@@ -1908,6 +1908,9 @@ var setLocalStorage = function (key, value) {
1908
1908
  var settings = {
1909
1909
  renderBy: 'Surface Type',
1910
1910
  showStory: 'All Stories',
1911
+ showAirLoop: 'All Loops',
1912
+ findAdjacencyIssues: false,
1913
+ findAdjacencyThreshold: 1,
1911
1914
  searchType: getStringFromLocalStorage('searchType', 'Surfaces'),
1912
1915
  searchName: getStringFromLocalStorage('searchName', ''),
1913
1916
  showFloors: getBoolFromLocalStorage('showFloors', true),
@@ -2295,11 +2298,13 @@ function init(os_data_in) {
2295
2298
  orthographicControls.minDistance = 10;
2296
2299
  orthographicControls.maxDistance = 1000;
2297
2300
  orthographicControls.enabled = true;
2301
+ orthographicControls.addEventListener('change', requestRenderIfNotRequested);
2298
2302
 
2299
2303
  perspectiveControls = new THREE.OrbitControls(perspectiveCamera, renderer.domElement);
2300
2304
  perspectiveControls.minDistance = 10;
2301
2305
  perspectiveControls.maxDistance = 1000;
2302
2306
  perspectiveControls.enabled = true;
2307
+ perspectiveControls.addEventListener('change', requestRenderIfNotRequested);
2303
2308
 
2304
2309
  // initialize camera and controls
2305
2310
  setAllCameraAngles(-30, 30, 0);
@@ -2406,6 +2411,8 @@ function init(os_data_in) {
2406
2411
  shininess: 50,
2407
2412
  side: THREE.DoubleSide
2408
2413
  });
2414
+
2415
+ dot_material = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false, color: 0xff0000 } );
2409
2416
 
2410
2417
  materials = parseMaterials(os_data.materials);
2411
2418
 
@@ -2543,6 +2550,7 @@ function onDocumentMouseClick(event) {
2543
2550
  } else {
2544
2551
  removeSelection();
2545
2552
  }
2553
+ requestRenderIfNotRequested();
2546
2554
  }
2547
2555
  }
2548
2556
 
@@ -2622,8 +2630,10 @@ function displaySelectedObjectDetails() {
2622
2630
  document.body.style.cursor = 'pointer';
2623
2631
  }
2624
2632
 
2625
- function animate(timestamp) {
2626
- requestAnimationFrame(animate);
2633
+ let renderRequested = false;
2634
+
2635
+ function animate() {
2636
+ renderRequested = undefined;
2627
2637
  orthographicControls.update();
2628
2638
  perspectiveControls.update();
2629
2639
  if (settings.orthographic){
@@ -2633,6 +2643,13 @@ function animate(timestamp) {
2633
2643
  }
2634
2644
  }
2635
2645
 
2646
+ function requestRenderIfNotRequested() {
2647
+ if (!renderRequested) {
2648
+ renderRequested = true;
2649
+ requestAnimationFrame(animate);
2650
+ }
2651
+ }
2652
+
2636
2653
  function erf(x) {
2637
2654
  // constants
2638
2655
  var a1 = 0.254829592;
@@ -2683,6 +2700,100 @@ function cycleHour() {
2683
2700
  }
2684
2701
  }
2685
2702
 
2703
+ var adjacencyIssueIds = new Set();
2704
+ var adjacencyIssueVertices = new Set();
2705
+ var updateAdjacencyIssues = function(value) {
2706
+ Array.groupBy = function(arr, prop) {
2707
+ return arr.reduce(function(groups, item) {
2708
+ const val = prop.split('.')
2709
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined') ? obj[key] : undefined, item);
2710
+ groups[val] = groups[val] || [];
2711
+ groups[val].push(item);
2712
+ return groups;
2713
+ }, {});
2714
+ }
2715
+
2716
+ function combinations(a, b) {
2717
+ if (b === undefined) {
2718
+ return a.flatMap((v, i) => a.slice(i).map(w => [v, w]));
2719
+ } else {
2720
+ return a.flatMap((v, i) => b.map(w => [v, w]));
2721
+ }
2722
+ }
2723
+
2724
+ // As of now Three.js revision 71
2725
+ class Box3 extends THREE.Box3 {
2726
+
2727
+ // Added in revision 84
2728
+ expandByObject(object) {
2729
+ const box = new THREE.Box3();
2730
+ box.setFromObject(object);
2731
+ this.expandByPoint(box.min);
2732
+ this.expandByPoint(box.max);
2733
+ }
2734
+
2735
+ // Added in revision 74
2736
+ intersectsBox(box) {
2737
+ // using 6 splitting planes to rule out intersections.
2738
+ return box.max.x < this.min.x || box.min.x > this.max.x ||
2739
+ box.max.y < this.min.y || box.min.y > this.max.y ||
2740
+ box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
2741
+ }
2742
+ }
2743
+
2744
+ const detectable = scene_objects.filter(o =>
2745
+ ["Wall", "RoofCeiling", "Floor"].includes(o.userData.surfaceTypeMaterialName))
2746
+ const per_space = Array.groupBy(detectable, 'userData.spaceName')
2747
+ const space_boxes = Object.entries(per_space).map(([space, objects]) => {
2748
+ const box = new Box3();
2749
+ box.space = space;
2750
+ box.surfaces = objects;
2751
+ objects.forEach(o => box.expandByObject(o));
2752
+ box.expandByScalar(0.5);
2753
+ return box;
2754
+ });
2755
+
2756
+ /*
2757
+ * Implements part of Honeybee's SolveAdj tool licensed under the AGPL 3.0. See:
2758
+ * - https://github.com/ladybug-tools/honeybee-grasshopper-core/blob/27773fe0097188d4be0e160c71a0cda2c54c6f73/honeybee_grasshopper_core/src/HB%20Solve%20Adjacency.py#L190
2759
+ * - https://github.com/ladybug-tools/honeybee-core/blob/ae4e905a78635a7448291ff8dbe94aa2f627a1ae/honeybee/room.py#L925
2760
+ * - https://github.com/ladybug-tools/honeybee-core/blob/ae4e905a78635a7448291ff8dbe94aa2f627a1ae/honeybee/room.py#L867
2761
+ * - https://github.com/ladybug-tools/ladybug-geometry/blob/da34f3397c59bc311004cb6319d534953c8ee9ab/ladybug_geometry/geometry3d/polyface.py#L689
2762
+ */
2763
+ const almost_equal = 1e-6;
2764
+ const thresh = (parseFloat(settings.findAdjacencyThreshold)**2)/10000;
2765
+ adjacencyIssueIds.clear();
2766
+ adjacencyIssueVertices.clear();
2767
+
2768
+ // issues within space
2769
+ space_boxes.forEach(a => {
2770
+ for (var [p, q] of combinations(a.surfaces)) {
2771
+ for (var [x, y] of combinations(p.geometry.vertices, q.geometry.vertices)) {
2772
+ const dist = x.distanceToSquared(y);
2773
+ if (almost_equal < dist && dist < thresh) {
2774
+ adjacencyIssueIds.add(p.id).add(q.id);
2775
+ adjacencyIssueVertices.add(x).add(y);
2776
+ }
2777
+ }
2778
+ }
2779
+ })
2780
+
2781
+ // issues between spaces
2782
+ for (var [a, b] of combinations(space_boxes)) {
2783
+ if (a.intersectsBox(b)) {
2784
+ for (var [p, q] of combinations(a.surfaces, b.surfaces)) {
2785
+ for (var [x, y] of combinations(p.geometry.vertices, q.geometry.vertices)) {
2786
+ const dist = x.distanceToSquared(y);
2787
+ if (almost_equal < dist && dist < thresh) {
2788
+ adjacencyIssueIds.add(p.id).add(q.id);
2789
+ adjacencyIssueVertices.add(x).add(y);
2790
+ }
2791
+ }
2792
+ }
2793
+ }
2794
+ }
2795
+ }
2796
+
2686
2797
  var gui = null;
2687
2798
  var dataFolder = null;
2688
2799
  var update = function (value) {
@@ -2770,9 +2881,16 @@ var update = function (value) {
2770
2881
 
2771
2882
  object.visible = true;
2772
2883
 
2773
- if (settings.showStory == 'All Stories' || settings.showStory == object.userData.buildingStoryName){
2774
- // no-op
2775
- }else{
2884
+ if (settings.findAdjacencyIssues) {
2885
+ object.visible = adjacencyIssueIds.has(object.id);
2886
+ }
2887
+
2888
+ if (settings.showStory !== 'All Stories' && settings.showStory !== object.userData.buildingStoryName) {
2889
+ object.visible = false;
2890
+ }
2891
+ if ((settings.showAirLoop !== 'All Loops' && !object.userData.airLoopHVACNames.includes(settings.showAirLoop))
2892
+ &&
2893
+ (settings.showAirLoop !== 'No Loop' || object.userData.airLoopHVACNames.length !== 0)) {
2776
2894
  object.visible = false;
2777
2895
  }
2778
2896
 
@@ -2863,7 +2981,7 @@ var update = function (value) {
2863
2981
  keyName = object_variable.keyName;
2864
2982
  }
2865
2983
  }
2866
-
2984
+
2867
2985
  if (value !== null) {
2868
2986
  object.userData.variableName = settings.variableName;
2869
2987
  object.userData.variableDate = date;
@@ -2875,7 +2993,7 @@ var update = function (value) {
2875
2993
  object.userData.variableName = settings.variableName;
2876
2994
  object.userData.variableDate = date;
2877
2995
  object.userData.variableTime = time;
2878
- object.userData.variableKeyName = keyName;
2996
+ object.userData.variableKeyName = keyName;
2879
2997
  object.userData.variableValue = '';
2880
2998
  object.userData.variableUnits = units;
2881
2999
  }
@@ -2884,7 +3002,7 @@ var update = function (value) {
2884
3002
  material.color.set(getColor(value, variable.valueMin, variable.valueMax, settings.colorScheme));
2885
3003
  break;
2886
3004
  }
2887
-
3005
+
2888
3006
  if (!material) {
2889
3007
  material = unknown_material;
2890
3008
  }
@@ -2926,7 +3044,7 @@ var update = function (value) {
2926
3044
  // coincident object is visible, hide back object
2927
3045
  back_object.visible = false;
2928
3046
  }else{
2929
-
3047
+
2930
3048
  if (back_object.material){
2931
3049
  // coincident object is not visible, show back object
2932
3050
  back_object.visible = true;
@@ -2942,6 +3060,27 @@ var update = function (value) {
2942
3060
  }
2943
3061
  }
2944
3062
  });
3063
+
3064
+ if (dot_points instanceof THREE.Points){
3065
+ scene.remove(dot_points);
3066
+ dot_points = null;
3067
+ }
3068
+
3069
+ if (settings.findAdjacencyIssues) {
3070
+ var dot_geometry = new THREE.Geometry();
3071
+ dot_points = new THREE.Points(dot_geometry, dot_material);
3072
+
3073
+ adjacencyIssueVertices.forEach(function(p) {
3074
+ dot_geometry.vertices.push(p);
3075
+ });
3076
+
3077
+ dot_geometry.verticesNeedUpdate = true;
3078
+ dot_geometry.elementsNeedUpdate = true;
3079
+ dot_geometry.computeVertexNormals();
3080
+ scene.add(dot_points);
3081
+ }
3082
+
3083
+ requestRenderIfNotRequested();
2945
3084
  };
2946
3085
 
2947
3086
  var updateVariable = function (variableName) {
@@ -2973,13 +3112,27 @@ var initDatGui = function () {
2973
3112
  update(value);
2974
3113
  });
2975
3114
 
2976
- building_story_names = os_data.metadata.buildingStoryNames;
3115
+ var building_story_names = os_data.metadata.buildingStoryNames;
2977
3116
  building_story_names.unshift('All Stories');
2978
3117
  gui.add(settings, 'showStory', building_story_names).name('Show Story').onChange(function(value) {
2979
3118
  removeSelection();
2980
3119
  update(value);
2981
3120
  });
2982
3121
 
3122
+ var air_loop_names = os_data.metadata
3123
+ .modelObjectMetadata
3124
+ .filter(objMetaData => objMetaData.iddObjectType === "OS:AirLoopHVAC")
3125
+ .map(objMetaData => objMetaData.name)
3126
+ .sort();
3127
+ if (air_loop_names && air_loop_names.length > 0) {
3128
+ air_loop_names.unshift("All Loops");
3129
+ air_loop_names.unshift("No Loop");
3130
+ gui.add(settings, 'showAirLoop', air_loop_names).name('Show Air Loop').onChange(function (value) {
3131
+ removeSelection();
3132
+ update(value);
3133
+ });
3134
+ }
3135
+
2983
3136
  var s1 = gui.addFolder('Search');
2984
3137
  search_types = ['Surfaces', 'Spaces and Groups']
2985
3138
  s1.add(settings, 'searchType', search_types).name('Search Type').onChange(function (value) {
@@ -3037,16 +3190,33 @@ var initDatGui = function () {
3037
3190
  });
3038
3191
  f1.open();
3039
3192
 
3040
- var f2 = gui.addFolder('Camera');
3041
- f2.add(settings, 'orthographic').name('Orthographic').onChange(function(value) {
3042
- setLocalStorage('orthographic', value);
3193
+ var f2 = gui.addFolder('Potential Adjacency Issues');
3194
+ f2.add(settings, 'findAdjacencyIssues').name('Enable').onChange(value => {
3195
+ removeSelection();
3196
+ setLocalStorage('findAdjacencyThreshold', value);
3197
+ updateAdjacencyIssues();
3198
+ update(value);
3199
+ });
3200
+ f2.add(settings, 'findAdjacencyThreshold', 0.1, 10, 0.5).name('Threshold').onFinishChange(function (value) {
3201
+ if (settings.findAdjacencyIssues) {
3202
+ removeSelection();
3203
+ setLocalStorage('findAdjacencyThreshold', value);
3204
+ updateAdjacencyIssues();
3205
+ update(value);
3206
+ }
3043
3207
  });
3044
- f2.add(settings, 'xView').name('X View');
3045
- f2.add(settings, 'yView').name('Y View');
3046
- f2.add(settings, 'zView').name('Z View');
3047
- f2.add(settings, 'reset').name('Reset');
3048
3208
  f2.open();
3049
3209
 
3210
+ var f3 = gui.addFolder('Camera');
3211
+ f3.add(settings, 'orthographic').name('Orthographic').onChange(function (value) {
3212
+ setLocalStorage('orthographic', value);
3213
+ });
3214
+ f3.add(settings, 'xView').name('X View');
3215
+ f3.add(settings, 'yView').name('Y View');
3216
+ f3.add(settings, 'zView').name('Z View');
3217
+ f3.add(settings, 'reset').name('Reset');
3218
+ f3.open();
3219
+
3050
3220
  /*var f2 = gui.addFolder('Section Cut');
3051
3221
  f2.add(settings, 'xSection', 0, 360).name('X Section').onChange(function (value) {
3052
3222
  console.log('X cut: ' + value);
@@ -228,6 +228,7 @@ class VA3C
228
228
  materials << make_material('Boundary_Outdoors_Wind', format_color(9, 159, 162), 1, THREE::DoubleSide)
229
229
  materials << make_material('Boundary_Outdoors_SunWind', format_color(68, 119, 161), 1, THREE::DoubleSide)
230
230
  materials << make_material('Boundary_Ground', format_color(204, 183, 122), 1, THREE::DoubleSide)
231
+ materials << make_material('Boundary_Foundation', format_color(117, 30, 122), 1, THREE::DoubleSide)
231
232
  materials << make_material('Boundary_Groundfcfactormethod', format_color(153, 122, 30), 1, THREE::DoubleSide)
232
233
  materials << make_material('Boundary_Groundslabpreprocessoraverage', format_color(255, 191, 0), 1, THREE::DoubleSide)
233
234
  materials << make_material('Boundary_Groundslabpreprocessorcore', format_color(255, 182, 50), 1, THREE::DoubleSide)
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>view_model</name>
5
5
  <uid>f4669f10-fda5-489d-8e1c-7ca3c2d40378</uid>
6
- <version_id>8e4cf2b6-75ec-406e-8bd6-e1f4367e81f5</version_id>
7
- <version_modified>20210801T054201Z</version_modified>
6
+ <version_id>53a5f6c1-15cc-4df4-973c-62f725cd268e</version_id>
7
+ <version_modified>20220505T194724Z</version_modified>
8
8
  <xml_checksum>1E1F8B97</xml_checksum>
9
9
  <class_name>ViewModel</class_name>
10
10
  <display_name>ViewModel</display_name>
@@ -53,12 +53,6 @@
53
53
  <usage_type>test</usage_type>
54
54
  <checksum>AC094EF8</checksum>
55
55
  </file>
56
- <file>
57
- <filename>va3c.rb</filename>
58
- <filetype>rb</filetype>
59
- <usage_type>resource</usage_type>
60
- <checksum>1FD61D41</checksum>
61
- </file>
62
56
  <file>
63
57
  <version>
64
58
  <software_program>OpenStudio</software_program>
@@ -88,11 +82,17 @@
88
82
  <usage_type>readmeerb</usage_type>
89
83
  <checksum>703C9964</checksum>
90
84
  </file>
85
+ <file>
86
+ <filename>va3c.rb</filename>
87
+ <filetype>rb</filetype>
88
+ <usage_type>resource</usage_type>
89
+ <checksum>78ACC264</checksum>
90
+ </file>
91
91
  <file>
92
92
  <filename>report.html.in</filename>
93
93
  <filetype>in</filetype>
94
94
  <usage_type>resource</usage_type>
95
- <checksum>E7E95149</checksum>
95
+ <checksum>A57477D9</checksum>
96
96
  </file>
97
97
  </files>
98
98
  </measure>