openstudio-standards 0.8.5 → 0.8.7
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/data/standards/test_performance_expected_dd_results.csv +90 -90
- data/lib/openstudio-standards/btap/activity.rb +858 -61
- data/lib/openstudio-standards/btap/attributes.rb +297 -103
- data/lib/openstudio-standards/btap/bridging.rb +1335 -593
- data/lib/openstudio-standards/btap/btap.rb +60 -181
- data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +199 -142
- data/lib/openstudio-standards/btap/common/constructions.json +1275 -0
- data/lib/openstudio-standards/btap/common/costs.csv +1969 -0
- data/lib/openstudio-standards/btap/common/costs_local_factors.csv +2315 -0
- data/lib/openstudio-standards/btap/common/materials_glazing.csv +61 -0
- data/lib/openstudio-standards/btap/{common_resources → common}/materials_hvac.csv +1685 -1685
- data/lib/openstudio-standards/btap/{common_resources → common}/materials_lighting.csv +266 -266
- data/lib/openstudio-standards/btap/common/materials_opaque.csv +214 -0
- data/lib/openstudio-standards/btap/common/necb_building_types.csv +35 -0
- data/lib/openstudio-standards/btap/common/necb_space_types.csv +110 -0
- data/lib/openstudio-standards/btap/common/thermal_bridging.csv +73 -0
- data/lib/openstudio-standards/btap/costing/btap_costing.rb +346 -429
- data/lib/openstudio-standards/btap/costing/database.rb +104 -0
- data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +356 -344
- data/lib/openstudio-standards/btap/costing/dcv_costing.rb +282 -296
- data/lib/openstudio-standards/btap/costing/envelope_costing.rb +179 -192
- data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2477 -2316
- data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +127 -142
- data/lib/openstudio-standards/btap/costing/lighting_costing.rb +216 -198
- data/lib/openstudio-standards/btap/costing/nv_costing.rb +522 -523
- data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +649 -649
- data/lib/openstudio-standards/btap/costing/shw_costing.rb +626 -625
- data/lib/openstudio-standards/btap/costing/thermal_bridging_costing.rb +72 -0
- data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2363 -2361
- data/lib/openstudio-standards/btap/deprecated.rb +1033 -0
- data/lib/openstudio-standards/btap/envelope.rb +313 -572
- data/lib/openstudio-standards/btap/fileio.rb +152 -1070
- data/lib/openstudio-standards/btap/geometry.rb +486 -766
- data/lib/openstudio-standards/btap/linear_regression.rb +130 -0
- data/lib/openstudio-standards/btap/paths.rb +46 -0
- data/lib/openstudio-standards/btap/qaqc/analysis.rb +163 -0
- data/lib/openstudio-standards/btap/qaqc/data.rb +2293 -0
- data/lib/openstudio-standards/btap/qaqc/datapoint.rb +641 -0
- data/lib/openstudio-standards/btap/schedules.rb +11 -611
- data/lib/openstudio-standards/btap/structure.rb +574 -189
- data/lib/openstudio-standards/constructions/materials/information.rb +1 -1
- data/lib/openstudio-standards/create_typical/create_typical.rb +1 -1
- data/lib/openstudio-standards/exterior_lighting/create.rb +135 -85
- data/lib/openstudio-standards/exterior_lighting/data/typical_exterior_lighting.json +20 -0
- data/lib/openstudio-standards/exterior_lighting/information.rb +23 -2
- data/lib/openstudio-standards/geometry/create.rb +7 -3
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +3 -2
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +3 -2
- data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +84 -84
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +4 -4
- data/lib/openstudio-standards/refrigeration/create_walkin.rb +45 -5
- data/lib/openstudio-standards/refrigeration/data/refrigerated_walkins.csv +75 -75
- data/lib/openstudio-standards/schedules/parametric.rb +6 -0
- data/lib/openstudio-standards/service_water_heating/create_typical.rb +10 -3
- data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +30 -14
- data/lib/openstudio-standards/service_water_heating/information.rb +4 -1
- data/lib/openstudio-standards/sql_file/unmet_hours.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +3 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +12 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +18432 -3072
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +26 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8532 -1422
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +26 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8532 -1422
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.computer_room_acs.json +30 -30
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7560 -1260
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +1 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +7560 -1260
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +3 -3
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +1 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +22 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +7236 -1206
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.furnaces.json +223 -19
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +37 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +3 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6900 -1150
- data/lib/openstudio-standards/standards/cbes/data/cbes.schedules.json +1 -1
- data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +1 -1
- data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/surface_thermal_transmittance.json +76 -40
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/surface_thermal_transmittance.json +76 -40
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +6 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/NECB2011_QAQC.json +2988 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +25 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +672 -534
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Hospital.osm +1791 -1792
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +7 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +7 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeHotel.osm +5 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeOffice.osm +8 -9
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +10 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +14 -15
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Outpatient.osm +7 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/surface_thermal_transmittance.json +76 -40
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +14 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +542 -130
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +30 -63
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +7 -2
- data/lib/openstudio-standards/standards/necb/NECB2015/data/surface_thermal_transmittance.json +90 -0
- data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +8 -6
- data/lib/openstudio-standards/standards/necb/NECB2017/data/surface_thermal_transmittance.json +76 -40
- data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +2 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +0 -117
- data/lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json +76 -45
- data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +218 -0
- data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +12 -7
- data/lib/openstudio-standards/standards/standard.rb +1 -1
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards.rb +9 -4
- metadata +59 -66
- data/data/inventory/thermal_bridging.csv +0 -90
- data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +0 -7962
- data/lib/openstudio-standards/btap/NECB_building_types.csv +0 -35
- data/lib/openstudio-standards/btap/NECB_space_types.csv +0 -109
- data/lib/openstudio-standards/btap/WeatherData1.json +0 -2110
- data/lib/openstudio-standards/btap/WeatherData1.xlsx +0 -0
- data/lib/openstudio-standards/btap/btap_result.rb +0 -1144
- data/lib/openstudio-standards/btap/btap_test_helper.rb +0 -86
- data/lib/openstudio-standards/btap/common_paths.rb +0 -81
- data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +0 -52
- data/lib/openstudio-standards/btap/common_resources/Constructions.csv +0 -37
- data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +0 -1270
- data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +0 -121
- data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +0 -2256
- data/lib/openstudio-standards/btap/common_resources/costs.csv +0 -1897
- data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +0 -2315
- data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +0 -35
- data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +0 -164
- data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +0 -359
- data/lib/openstudio-standards/btap/costing/btap_workflow.rb +0 -117
- data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +0 -11
- data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +0 -136
- data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +0 -173
- data/lib/openstudio-standards/btap/costing/dummy.epw +0 -8768
- data/lib/openstudio-standards/btap/costing/dummy.osm +0 -5320
- data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +0 -42
- data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +0 -225
- data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +0 -28705
- data/lib/openstudio-standards/btap/costing/parallel_tests.rb +0 -92
- data/lib/openstudio-standards/btap/costing/test_list.txt +0 -15
- data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +0 -27
- data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +0 -80
- data/lib/openstudio-standards/btap/necb_2011_spacetype_info.csv +0 -225
- data/lib/openstudio-standards/btap/utilities/Add_template_field_to_json.rb +0 -22
- data/lib/openstudio-standards/btap/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +0 -204
- data/lib/openstudio-standards/btap/utilities/generate_space_types.rb +0 -8
- data/lib/openstudio-standards/btap/utilities/necb_to_epw_map.rb +0 -50
- data/lib/openstudio-standards/btap/utilities/os_sim_extract.rb +0 -48
- data/lib/openstudio-standards/btap/utilities/rename_surfaces.rb +0 -24
- data/lib/openstudio-standards/btap/utilities/round_surf_coords.rb +0 -32
- data/lib/openstudio-standards/btap/utilities/sched_create.rb +0 -145
- data/lib/openstudio-standards/btap/utilities/set_mult_to_adiabatic.rb +0 -53
- data/lib/openstudio-standards/btap/utilities/space_type.rb +0 -78
- data/lib/openstudio-standards/btap/utilities/weatherData1_xlsx_to_json.rb +0 -56
- data/lib/openstudio-standards/btap/vintagizer.rb +0 -161
- data/lib/openstudio-standards/btap/visualization.rb +0 -72
- data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2011_spacetype_info.csv +0 -225
- data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +0 -79
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +0 -2656
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +0 -653
- data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +0 -28705
- data/lib/openstudio-standards/standards/necb/common/utility_pricing_2025-02-20.csv +0 -92
- /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_frame.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_glazing.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_opaque.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/hvac_vent_ahu.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/lighting.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/lighting_sets.csv +0 -0
- /data/lib/openstudio-standards/btap/{common_resources → common}/locations.csv +0 -0
- /data/lib/openstudio-standards/btap/{costing → common}/mech_sizing.json +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# **************************************************************************** /
|
|
2
|
-
# * Copyright (c) 2008-
|
|
2
|
+
# * Copyright (c) 2008-2026, Natural Resources Canada
|
|
3
3
|
# * All rights reserved.
|
|
4
4
|
# *
|
|
5
5
|
# * This library is free software; you can redistribute it and/or
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
# * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
18
|
# **************************************************************************** /
|
|
19
19
|
|
|
20
|
-
require "csv"
|
|
21
|
-
|
|
22
20
|
module BTAP
|
|
23
21
|
module ActivityData
|
|
24
22
|
##
|
|
@@ -36,8 +34,8 @@ module BTAP
|
|
|
36
34
|
# the repair or servicing of such vehicles.
|
|
37
35
|
#
|
|
38
36
|
# This mismatch, and other related issues of a similar nature, make it
|
|
39
|
-
# challenging to cross-compare NECB editions
|
|
40
|
-
#
|
|
37
|
+
# challenging to cross-compare NECB editions for instance. The 'exact' NECB
|
|
38
|
+
# spacetype strings shouldn't matter - they almost always reference the same
|
|
41
39
|
# building 'activity' (e.g. a facility where vehicles are parked/stored).
|
|
42
40
|
# BTAP should instead rely on abstract 'activity' designations, e.g.
|
|
43
41
|
# 'parking'. This requires module/class methods to extract specific keywords
|
|
@@ -48,13 +46,13 @@ module BTAP
|
|
|
48
46
|
# For instance, multi-unit residential buildings (MURBs), university/school
|
|
49
47
|
# dormitories and long-term care facilities are all grouped under "housing",
|
|
50
48
|
# which in turn sets building-wide 'structural' options, e.g. wood-framed
|
|
51
|
-
# (small-scale) vs reinforced concrete flat slab & post-beam (mid-
|
|
52
|
-
# scale
|
|
53
|
-
@@data = {bldg: {}, space: {}}
|
|
49
|
+
# (small-scale "housing") vs reinforced concrete flat slab & post-beam (mid-
|
|
50
|
+
# & large-scale "housing"). See lib/openstudio-standards/btap/structure.rb.
|
|
51
|
+
@@data = {bldg: {}, space: {}, ancillaries: [], auxiliaries: []}
|
|
54
52
|
|
|
55
53
|
# Hard setting path for both files (temporary @todo).
|
|
56
|
-
@@data[:bldg ][:file ] =
|
|
57
|
-
@@data[:space][:file ] =
|
|
54
|
+
@@data[:bldg ][:file ] = Paths::NECB_BUILDING_TYPES_PATH
|
|
55
|
+
@@data[:space][:file ] = Paths::NECB_SPACE_TYPES_PATH
|
|
58
56
|
@@data[:bldg ][:table ] = nil
|
|
59
57
|
@@data[:space][:table ] = nil
|
|
60
58
|
@@data[:bldg ][:activity ] = {}
|
|
@@ -62,27 +60,84 @@ module BTAP
|
|
|
62
60
|
@@data[:bldg ][:activities] = []
|
|
63
61
|
@@data[:bldg ][:categories] = []
|
|
64
62
|
|
|
63
|
+
# Key notes, common to NECB editions.
|
|
64
|
+
#
|
|
65
|
+
# Note to NECB Table 8.4.4.7.-A: (2) Small individual spaces in the
|
|
66
|
+
# proposed building that are located among larger spaces of another space
|
|
67
|
+
# type shall be considered ANCILLARY to that larger space: for example, a
|
|
68
|
+
# conference room serving office spaces would be grouped with the office
|
|
69
|
+
# spaces as one space type.
|
|
70
|
+
#
|
|
71
|
+
# A-8.4.3.2.(1): Tables [...] contain default values of operating
|
|
72
|
+
# schedules of building parameters for simulation purposes. These
|
|
73
|
+
# schedules MAY be used with Table A-8.4.3.2.(2)-B IF more accurate
|
|
74
|
+
# information IS NOT AVAILABLE.
|
|
75
|
+
#
|
|
76
|
+
# A-8.4.3.2.(2): Tables [...] contain representative internal and service
|
|
77
|
+
# water heating loads, operating schedules, and illuminance levels to be
|
|
78
|
+
# used as modeling GUIDANCE when actual values are not known.
|
|
79
|
+
#
|
|
80
|
+
# Note to Table A-8.4.3.3.(2)B. (1): An asterisk (*) in this column
|
|
81
|
+
# indicates that there is no recommended default schedule for the space
|
|
82
|
+
# type listed. In general, such space types will be simulated using a
|
|
83
|
+
# schedule that is similar to the ADJACENT spaces served: e.g. a corridor
|
|
84
|
+
# space serving an adjacent office space will be simulated using a
|
|
85
|
+
# schedule that is similar to that of the office space.
|
|
86
|
+
#
|
|
87
|
+
# This last note refers to the following NECB 'ancillary' spacetypes:
|
|
88
|
+
#
|
|
89
|
+
# 2011 2015 2017 2020
|
|
90
|
+
# @@data[:ancillaries] << "atrium::common" # C * * *
|
|
91
|
+
# @@data[:ancillaries] << "audience::common" # * * *
|
|
92
|
+
# @@data[:ancillaries] << "computer::common" # * * *
|
|
93
|
+
# @@data[:ancillaries] << "corridor::common" # * * * *
|
|
94
|
+
# @@data[:ancillaries] << "corridor::hospital" # * * * *
|
|
95
|
+
# @@data[:ancillaries] << "corridor::manufacturing" # * * * *
|
|
96
|
+
# @@data[:ancillaries] << "mechanical::common" # * * * *
|
|
97
|
+
# @@data[:ancillaries] << "locker::common" # * * * *
|
|
98
|
+
# @@data[:ancillaries] << "seating::common" # * * *
|
|
99
|
+
# @@data[:ancillaries] << "stairway::common" # * * * *
|
|
100
|
+
# @@data[:ancillaries] << "storage::common" # * * * *
|
|
101
|
+
# @@data[:ancillaries] << "washroom::common" # * * * *
|
|
102
|
+
|
|
103
|
+
# Note that NECB2011 recommends schedule set "C" for atria, while all other
|
|
104
|
+
# NECB editions point to Note (1) of Table A-8.4.3.3.(2)B (on schedule set
|
|
105
|
+
# inheritance). To facilitate cross-comparisons between NECB editions, the
|
|
106
|
+
# NECB 2011 atrium schedule set will harmonize with other NECB editions.
|
|
107
|
+
#
|
|
108
|
+
# With respect to other NECB editions, NECB2011 also has a few missing
|
|
109
|
+
# entries: There is neither GENERAL 'seating' (e.g. a waiting area) nor
|
|
110
|
+
# GENERAL 'audience seating' types: 'seating' is either building-SPECIFIC
|
|
111
|
+
# (e.g. transportation facility) or SPECIFIC 'audience seating' (e.g.
|
|
112
|
+
# theatre, convention centre). And there is no entry for computer or server
|
|
113
|
+
# rooms. Within the scope of BTAP::Activity, missing space types inherit
|
|
114
|
+
# fallbacks (e.g. audience seating, office).
|
|
115
|
+
|
|
65
116
|
# Parse building type data on file.
|
|
66
117
|
if File.exist?(@@data[:bldg][:file])
|
|
67
118
|
table = CSV.open(@@data[:bldg][:file], headers: true).read
|
|
68
119
|
|
|
69
|
-
# 35 unique entries (rows),
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
120
|
+
# 35 unique entries (rows), 10 columns per row, e.g.:
|
|
121
|
+
# C01 C02 C03 C04 C05 C06 C07 C08 C09 C10
|
|
122
|
+
# ____ ___ ____ ____ ___ ___ ________ _____ _______________ ____________
|
|
123
|
+
# care, 25, 1.5, 500, j, 13, housing, care, health/clinic/, residential
|
|
73
124
|
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
125
|
+
# C01: BTAP building ACTIVITY e.g. "care"
|
|
126
|
+
# C02: occupant density e.g. 25.0 m2/occupant
|
|
127
|
+
# C03: peak equipment load e.g. 1.5 W/m2
|
|
128
|
+
# C04: peak SWH load e.g. 500.0 W/occupant
|
|
129
|
+
# C05: schedule set e.g. "j"
|
|
130
|
+
# C06: non-occupant liveload e.g. 13 kg/m2, ~1/12 of NBC min liveload
|
|
131
|
+
# C07: BTAP building CATEGORY e.g. "housing"
|
|
132
|
+
# C08: selected sub-string(s) e.g. "care", as in "Long-term care"
|
|
133
|
+
# C09: rejected sub-string(s) e.g. "health", "multi", "residential"
|
|
134
|
+
# C10: fallback (if missing) e.g. "residential"
|
|
80
135
|
#
|
|
81
136
|
# Contrary to the aforementioned 'parking' case (where fortunately there
|
|
82
137
|
# is an obvious one-to-one match between "Parking garage" (NECB2011) and
|
|
83
138
|
# "Storage garage" (NECB2020)), there is no direct match here for a
|
|
84
139
|
# long-term care facility when using the NECB2011. In this case, the
|
|
85
|
-
# fallback 'activity' is 'residential' (
|
|
140
|
+
# fallback 'activity' is 'residential' (COL10). So in any cross-comparison
|
|
86
141
|
# of long-term care facilities between NECB editions, the NECB2011 variant
|
|
87
142
|
# would be akin to a MURB.
|
|
88
143
|
#
|
|
@@ -99,14 +154,18 @@ module BTAP
|
|
|
99
154
|
# COL4 substrings, then rejecting COL5 substrings, there should be a
|
|
100
155
|
# single selected row. See NECB unit test test_necb_activities.rb.
|
|
101
156
|
table.each do |row|
|
|
102
|
-
key = row[0]
|
|
157
|
+
key = row[0].to_s
|
|
103
158
|
|
|
104
159
|
@@data[:bldg][:activity][key] = {}
|
|
105
|
-
@@data[:bldg][:activity][key][:
|
|
106
|
-
@@data[:bldg][:activity][key][:
|
|
107
|
-
@@data[:bldg][:activity][key][:
|
|
108
|
-
@@data[:bldg][:activity][key][:
|
|
109
|
-
@@data[:bldg][:activity][key][:
|
|
160
|
+
@@data[:bldg][:activity][key][:density ] = row[1].to_f
|
|
161
|
+
@@data[:bldg][:activity][key][:eqpload ] = row[2].to_f
|
|
162
|
+
@@data[:bldg][:activity][key][:swhload ] = row[3].to_f
|
|
163
|
+
@@data[:bldg][:activity][key][:schedule] = row[4].to_s
|
|
164
|
+
@@data[:bldg][:activity][key][:liveload] = row[5].to_f
|
|
165
|
+
@@data[:bldg][:activity][key][:category] = row[6].to_s
|
|
166
|
+
@@data[:bldg][:activity][key][:includes] = row[7].to_s.split("/")
|
|
167
|
+
@@data[:bldg][:activity][key][:excludes] = row[8].to_s.split("/")
|
|
168
|
+
@@data[:bldg][:activity][key][:fallback] = row[9].to_s
|
|
110
169
|
end
|
|
111
170
|
|
|
112
171
|
# Keep CSV table. Ensure building activities & categories uniqueness. Add
|
|
@@ -125,16 +184,19 @@ module BTAP
|
|
|
125
184
|
if File.exist?(@@data[:space][:file])
|
|
126
185
|
table = CSV.open(@@data[:space][:file], headers: true).read
|
|
127
186
|
|
|
128
|
-
# 108 unique rows,
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
# "exhibit::convention, exhibit, museum, "
|
|
187
|
+
# 108 unique rows, 8 columns per row, e.g.:
|
|
188
|
+
# C01 C02 C03 C04 C05 C06 C07 C08
|
|
189
|
+
# ___________ ___ ____ ____ ____ ____ ____________ ___________________
|
|
190
|
+
# units::care, 25, 2.5, 500, j, unit, residential, units::residential
|
|
133
191
|
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
#
|
|
192
|
+
# C01: BTAP space ACTIVITY e.g. "units::care"
|
|
193
|
+
# C02: occupant density e.g. 25.0 m2/occupant
|
|
194
|
+
# C03: peak equipment load e.g. 2.5 W/m2
|
|
195
|
+
# C04: peak SWH load e.g. 500.0 W/occupant
|
|
196
|
+
# C05: schedule set e.g. "j"
|
|
197
|
+
# C06: selected sub-string(s) e.g. "unit"
|
|
198
|
+
# C07: rejected sub-string(s) e.g. "residential"
|
|
199
|
+
# C08: fallback (if missing) e.g. "units::residential"
|
|
138
200
|
#
|
|
139
201
|
# First, BTAP space 'activity' entries are namespaced, e.g.:
|
|
140
202
|
# - "units": 1-word descriptor on the nature of the space 'activity'
|
|
@@ -160,18 +222,29 @@ module BTAP
|
|
|
160
222
|
# share many features (e.g. sleeping, showers), yet each remains specific
|
|
161
223
|
# to an NECB space type entry (as required).
|
|
162
224
|
table.each do |row|
|
|
163
|
-
key = row[0]
|
|
225
|
+
key = row[0].to_s
|
|
164
226
|
str = key.split("::")
|
|
165
227
|
|
|
166
228
|
activity = str[0].to_s
|
|
167
229
|
bldgtype = str[1].to_s
|
|
230
|
+
schedule = row[4].to_s
|
|
168
231
|
|
|
169
232
|
@@data[:space][:activity][key] = {}
|
|
170
233
|
@@data[:space][:activity][key][:activity] = activity
|
|
171
234
|
@@data[:space][:activity][key][:bldgtype] = bldgtype
|
|
172
|
-
@@data[:space][:activity][key][:
|
|
173
|
-
@@data[:space][:activity][key][:
|
|
174
|
-
@@data[:space][:activity][key][:
|
|
235
|
+
@@data[:space][:activity][key][:density ] = row[1].to_f
|
|
236
|
+
@@data[:space][:activity][key][:eqpload ] = row[2].to_f
|
|
237
|
+
@@data[:space][:activity][key][:swhload ] = row[3].to_f
|
|
238
|
+
@@data[:space][:activity][key][:schedule] = schedule
|
|
239
|
+
@@data[:space][:activity][key][:includes] = row[5].to_s.split("/")
|
|
240
|
+
@@data[:space][:activity][key][:excludes] = row[6].to_s.split("/")
|
|
241
|
+
@@data[:space][:activity][key][:fallback] = row[7].to_s
|
|
242
|
+
|
|
243
|
+
if schedule == "*"
|
|
244
|
+
@@data[:ancillaries] << key
|
|
245
|
+
elsif schedule.include?("*")
|
|
246
|
+
@@data[:auxiliaries] << key
|
|
247
|
+
end
|
|
175
248
|
end
|
|
176
249
|
|
|
177
250
|
@@data[:space][:table] = table
|
|
@@ -179,6 +252,154 @@ module BTAP
|
|
|
179
252
|
# raise?
|
|
180
253
|
end
|
|
181
254
|
|
|
255
|
+
##
|
|
256
|
+
# Validates whether an activity is 'ancillary' to other(s). See relevant
|
|
257
|
+
# comments above, and note to Table A-8.4.3.3.(2)B. (1).
|
|
258
|
+
#
|
|
259
|
+
# @param activity [:to_sym] a BTAP::Activity keyword, e.g. "locker::common"
|
|
260
|
+
#
|
|
261
|
+
# @return [Boolean] whether activity is ancillary.
|
|
262
|
+
def ancillary?(activity = "")
|
|
263
|
+
return false unless activity.respond_to?(:to_sym)
|
|
264
|
+
|
|
265
|
+
activity = activity.to_s.strip.downcase
|
|
266
|
+
return true if @@data[:ancillaries].include?(activity)
|
|
267
|
+
|
|
268
|
+
false
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
##
|
|
272
|
+
# Validates whether an activity is 'auxiliary' to the building activity.
|
|
273
|
+
# 'Auxiliary' spaces differ from NECB 'ancillary' spaces. If requested by
|
|
274
|
+
# the user (in the .osm file), the former may adopt the dominant building
|
|
275
|
+
# activity schedule set, instead of the NECB suggested one. Examples include
|
|
276
|
+
# a school's gymnasium, cafeteria or auditorium.
|
|
277
|
+
#
|
|
278
|
+
# @param activity [:to_sym] a BTAP::Activity keyword, e.g. "court::gym"
|
|
279
|
+
#
|
|
280
|
+
# @return [Boolean] whether activity is auxiliary.
|
|
281
|
+
def auxiliary?(activity = "")
|
|
282
|
+
return false unless activity.respond_to?(:to_sym)
|
|
283
|
+
|
|
284
|
+
activity = activity.to_s.strip.downcase
|
|
285
|
+
return true if @@data[:auxiliaries].include?(activity)
|
|
286
|
+
|
|
287
|
+
false
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
##
|
|
291
|
+
# Validates whether an activity is considered 'wet', e.g. locker room.
|
|
292
|
+
#
|
|
293
|
+
# @param activity [:to_sym] a BTAP::Activity keyword, e.g. "locker::common"
|
|
294
|
+
#
|
|
295
|
+
# @return [Boolean] whether activity is 'wet'.
|
|
296
|
+
def wet?(activity = "")
|
|
297
|
+
return false unless activity.respond_to?(:to_sym)
|
|
298
|
+
|
|
299
|
+
activity = activity.to_s.strip.downcase
|
|
300
|
+
return true if activity.include?("locker")
|
|
301
|
+
return true if activity.include?("washroom")
|
|
302
|
+
|
|
303
|
+
false
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
##
|
|
307
|
+
# Validates whether a space is targeted by ANSI/IES Recommended Practice RP28
|
|
308
|
+
# 2007 - see store.accuristech.com/standards/ies-rp-28-07?product_id=1555565.
|
|
309
|
+
#
|
|
310
|
+
# @param space [OpenStudio::Model::Space] an OpenStudio space
|
|
311
|
+
#
|
|
312
|
+
# @return [Boolean] true if RP28'ed
|
|
313
|
+
def rp28?(space = nil)
|
|
314
|
+
return false unless space.is_a?(OpenStudio::Model::Space)
|
|
315
|
+
|
|
316
|
+
# First check AdditionalProperty.
|
|
317
|
+
tag = "rp28"
|
|
318
|
+
rp28 = space.additionalProperties.getFeatureAsBoolean(tag)
|
|
319
|
+
return rp28.get unless rp28.empty?
|
|
320
|
+
|
|
321
|
+
# Check spacetype strings.
|
|
322
|
+
variants = ["rp28", "rp-28", "rp_28", "rp 28"]
|
|
323
|
+
|
|
324
|
+
unless space.spaceType.empty?
|
|
325
|
+
type = space.spaceType.get
|
|
326
|
+
tID = type.nameString.downcase
|
|
327
|
+
|
|
328
|
+
if variants.any? { |variant| tID.include?(variant) }
|
|
329
|
+
return space.additionalProperties.setFeature(tag, true)
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
unless type.standardsSpaceType.empty?
|
|
333
|
+
stype = type.standardsSpaceType.get.downcase
|
|
334
|
+
|
|
335
|
+
if variants.any? { |variant| stype.include?(variant) }
|
|
336
|
+
return space.additionalProperties.setFeature(tag, true)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Check space identifier.
|
|
342
|
+
sID = space.nameString.downcase
|
|
343
|
+
|
|
344
|
+
if variants.any? { |variant| sID.include?(variant) }
|
|
345
|
+
return space.additionalProperties.setFeature(tag, true)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
space.additionalProperties.setFeature(tag, false)
|
|
349
|
+
|
|
350
|
+
false
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
##
|
|
354
|
+
# Validates whether a space is targeted for occupancy-sensing lighting
|
|
355
|
+
# control, per NECB2011.
|
|
356
|
+
#
|
|
357
|
+
# @param space [OpenStudio::Model::Space] an OpenStudio space
|
|
358
|
+
#
|
|
359
|
+
# @return [Boolean] true if occsensing
|
|
360
|
+
def occsensing_deprecated?(space = nil)
|
|
361
|
+
return false unless space.is_a?(OpenStudio::Model::Space)
|
|
362
|
+
|
|
363
|
+
# First check AdditionalProperty.
|
|
364
|
+
tag = "occsensing"
|
|
365
|
+
osns = space.additionalProperties.getFeatureAsBoolean(tag)
|
|
366
|
+
return osns.get unless osns.empty?
|
|
367
|
+
|
|
368
|
+
# Check spacetype strings.
|
|
369
|
+
variants = ["occ sens", "occ-sens", "occsens"]
|
|
370
|
+
|
|
371
|
+
unless space.spaceType.empty?
|
|
372
|
+
type = space.spaceType.get
|
|
373
|
+
tID = type.nameString.downcase
|
|
374
|
+
|
|
375
|
+
if variants.any? { |variant| tID.include?(variant) }
|
|
376
|
+
space.additionalProperties.setFeature(tag, true)
|
|
377
|
+
return true
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
unless type.standardsSpaceType.empty?
|
|
381
|
+
stype = type.standardsSpaceType.get.downcase
|
|
382
|
+
|
|
383
|
+
if variants.any? { |variant| stype.include?(variant) }
|
|
384
|
+
space.additionalProperties.setFeature(tag, true)
|
|
385
|
+
return true
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# Check space identifier.
|
|
391
|
+
sID = space.nameString.downcase
|
|
392
|
+
|
|
393
|
+
if variants.any? { |variant| sID.include?(variant) }
|
|
394
|
+
space.additionalProperties.setFeature(tag, true)
|
|
395
|
+
return true
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
space.additionalProperties.setFeature(tag, false)
|
|
399
|
+
|
|
400
|
+
false
|
|
401
|
+
end
|
|
402
|
+
|
|
182
403
|
##
|
|
183
404
|
# Returns BTAP Activity data.
|
|
184
405
|
#
|
|
@@ -195,16 +416,16 @@ module BTAP
|
|
|
195
416
|
class BTAP::Activity
|
|
196
417
|
extend ActivityData
|
|
197
418
|
|
|
198
|
-
# @return [String] assigned or inferred building ACTIVITY
|
|
419
|
+
# @return [String] assigned or inferred building ACTIVITY, e.g. "warehouse"
|
|
199
420
|
attr_reader :activity
|
|
200
421
|
|
|
201
|
-
# @return [Hash] collection of space ACTIVITIES
|
|
422
|
+
# @return [Hash] collection of space ACTIVITIES, e.g. "bulk::warehouse"
|
|
202
423
|
attr_reader :activities
|
|
203
424
|
|
|
204
|
-
# @return [String] building type CATEGORY
|
|
425
|
+
# @return [String] building type CATEGORY, e.g. "industry"
|
|
205
426
|
attr_reader :category
|
|
206
427
|
|
|
207
|
-
# @return [Float] expected non-occupant liveload
|
|
428
|
+
# @return [Float] expected non-occupant liveload, e.g. 90 kg/m2
|
|
208
429
|
attr_reader :liveload
|
|
209
430
|
|
|
210
431
|
# @return [Hash] logged messages
|
|
@@ -215,7 +436,8 @@ module BTAP
|
|
|
215
436
|
# Initialize BTAP Activity parameters.
|
|
216
437
|
#
|
|
217
438
|
# @param model [OpenStudio::Model::Model] a model
|
|
218
|
-
|
|
439
|
+
# @param option ["", "structure"] construction option
|
|
440
|
+
def initialize(model = nil, option = "")
|
|
219
441
|
mth = "BTAP::Activity::#{__callee__}"
|
|
220
442
|
@feedback = {logs: []}
|
|
221
443
|
lgs = @feedback[:logs]
|
|
@@ -228,6 +450,8 @@ module BTAP
|
|
|
228
450
|
return
|
|
229
451
|
end
|
|
230
452
|
|
|
453
|
+
option = "" unless option == "structure"
|
|
454
|
+
|
|
231
455
|
# Tag spaces as un/conditioned with "space_conditioning_category". For
|
|
232
456
|
# now, this is simply determined based on whether spaces are:
|
|
233
457
|
# - part of the total floor area (i.e. occupied)
|
|
@@ -252,7 +476,11 @@ module BTAP
|
|
|
252
476
|
space.additionalProperties.setFeature(tag, "nonresconditioned")
|
|
253
477
|
else
|
|
254
478
|
if space.nameString.downcase.include?("attic")
|
|
255
|
-
|
|
479
|
+
if option.empty?
|
|
480
|
+
space.additionalProperties.setFeature(tag, "nonresconditioned")
|
|
481
|
+
else
|
|
482
|
+
space.additionalProperties.setFeature(tag, "unconditioned")
|
|
483
|
+
end
|
|
256
484
|
else # treat all other cases as indirectly-conditioned e.g. plenums
|
|
257
485
|
space.additionalProperties.setFeature(tag, "nonresconditioned")
|
|
258
486
|
end
|
|
@@ -260,8 +488,8 @@ module BTAP
|
|
|
260
488
|
end
|
|
261
489
|
|
|
262
490
|
# Determine activities of occupied spaces in the model, then building.
|
|
263
|
-
@activities = self.
|
|
264
|
-
@activity = self.
|
|
491
|
+
@activities = self.spaceActivities(model)
|
|
492
|
+
@activity = self.buildingActivity(model)
|
|
265
493
|
@liveload = data[:bldg][:activity][@activity][:liveload]
|
|
266
494
|
|
|
267
495
|
# Assign building category.
|
|
@@ -269,6 +497,12 @@ module BTAP
|
|
|
269
497
|
@category = data[:bldg][:activity][@activity][:category]
|
|
270
498
|
end
|
|
271
499
|
|
|
500
|
+
# Assign schedules to auxiliary spaces - if present.
|
|
501
|
+
self.assignAuxiliarySchedules(self.buildingActivity?(model))
|
|
502
|
+
|
|
503
|
+
# Assign schedules to ancillary spaces - if present.
|
|
504
|
+
self.assignAncillarySchedules
|
|
505
|
+
|
|
272
506
|
true
|
|
273
507
|
end
|
|
274
508
|
|
|
@@ -278,10 +512,14 @@ module BTAP
|
|
|
278
512
|
# @param model [OpenStudio::Model::Model] a model
|
|
279
513
|
#
|
|
280
514
|
# @return [Hash] a collection of space activities (see logs if empty)
|
|
281
|
-
def
|
|
515
|
+
def spaceActivities(model = nil)
|
|
516
|
+
lgs = @feedback[:logs]
|
|
282
517
|
mth = "BTAP::Activity::#{__callee__}"
|
|
283
|
-
|
|
284
|
-
|
|
518
|
+
|
|
519
|
+
unless model.is_a?(OpenStudio::Model::Model)
|
|
520
|
+
lgs << "Invalid or empty OpenStudio model (#{mth})"
|
|
521
|
+
return {}
|
|
522
|
+
end
|
|
285
523
|
|
|
286
524
|
activities = {}
|
|
287
525
|
|
|
@@ -316,7 +554,7 @@ module BTAP
|
|
|
316
554
|
fallbacks << fallback unless fallback.empty?
|
|
317
555
|
end
|
|
318
556
|
|
|
319
|
-
# Reject if matching excluded
|
|
557
|
+
# Reject if matching any excluded keyword.
|
|
320
558
|
data[:space][:activity].each do |k, v|
|
|
321
559
|
v[:excludes].each do |kword|
|
|
322
560
|
candidates.delete(k) if standards.include?(kword)
|
|
@@ -339,11 +577,16 @@ module BTAP
|
|
|
339
577
|
end
|
|
340
578
|
|
|
341
579
|
entry = {}
|
|
342
|
-
entry[:m2 ] = space.floorArea
|
|
580
|
+
entry[:m2 ] = space.floorArea * space.multiplier
|
|
343
581
|
entry[:spacetype] = spacetype
|
|
344
582
|
entry[:standards] = standards
|
|
583
|
+
entry[:keyword ] = candidate
|
|
345
584
|
entry[:activity ] = data[:space][:activity][candidate][:activity]
|
|
346
585
|
entry[:bldgtype ] = data[:space][:activity][candidate][:bldgtype]
|
|
586
|
+
entry[:density ] = data[:space][:activity][candidate][:density]
|
|
587
|
+
entry[:eqpload ] = data[:space][:activity][candidate][:eqpload]
|
|
588
|
+
entry[:swhload ] = data[:space][:activity][candidate][:swhload]
|
|
589
|
+
entry[:schedule ] = data[:space][:activity][candidate][:schedule]
|
|
347
590
|
|
|
348
591
|
activities[space] = entry
|
|
349
592
|
end
|
|
@@ -356,11 +599,15 @@ module BTAP
|
|
|
356
599
|
#
|
|
357
600
|
# @param model OpenStudio::Model::Model] a model
|
|
358
601
|
#
|
|
359
|
-
# @return [String]
|
|
360
|
-
def
|
|
602
|
+
# @return [String] a model's general activity (see logs if empty)
|
|
603
|
+
def buildingActivity(model = nil)
|
|
604
|
+
lgs = @feedback[:logs]
|
|
361
605
|
mth = "BTAP::Activity::#{__callee__}"
|
|
362
|
-
|
|
363
|
-
|
|
606
|
+
|
|
607
|
+
unless model.is_a?(OpenStudio::Model::Model)
|
|
608
|
+
lgs << "Invalid or empty OpenStudio model (#{mth})"
|
|
609
|
+
return "office"
|
|
610
|
+
end
|
|
364
611
|
|
|
365
612
|
# OPTION A: Extract building activity from user-set 'additionalProperty'.
|
|
366
613
|
tag = "btap_building_activity"
|
|
@@ -441,8 +688,7 @@ module BTAP
|
|
|
441
688
|
# - "motion picture theatre"
|
|
442
689
|
#
|
|
443
690
|
# ... except for "auditorium". No NECB edition holds an "auditorium"
|
|
444
|
-
# building type entry. For the moment, "auditorium"
|
|
445
|
-
# with the ubiquitous high-school or college auditorium.
|
|
691
|
+
# building type entry. For the moment, "auditorium" == "theatre".
|
|
446
692
|
if activity == "common"
|
|
447
693
|
activities = {}
|
|
448
694
|
|
|
@@ -455,7 +701,7 @@ module BTAP
|
|
|
455
701
|
end
|
|
456
702
|
|
|
457
703
|
activity = case activities.sort.reverse.to_h.keys.first
|
|
458
|
-
when "audience" then "
|
|
704
|
+
when "audience" then "theatre"
|
|
459
705
|
when "sales" then "retail"
|
|
460
706
|
when "dining" then "restaurant"
|
|
461
707
|
when "cuisine" then "restaurant"
|
|
@@ -472,9 +718,560 @@ module BTAP
|
|
|
472
718
|
end
|
|
473
719
|
end
|
|
474
720
|
|
|
475
|
-
|
|
721
|
+
# Log warning.
|
|
722
|
+
if activity.empty?
|
|
723
|
+
lgs << "Assigning building activity 'office' (#{mth})"
|
|
724
|
+
activity = "office"
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
activity = "hospital" if activity == "health"
|
|
476
728
|
|
|
477
729
|
activity
|
|
478
730
|
end
|
|
731
|
+
|
|
732
|
+
##
|
|
733
|
+
# Validates whether user has explicitly set a valid building activity
|
|
734
|
+
# AdditionalProperty.
|
|
735
|
+
#
|
|
736
|
+
# @param model [OpenStudio::Model::Model] a model
|
|
737
|
+
#
|
|
738
|
+
# @return [Boolean] true if a valid building activity is set by user.
|
|
739
|
+
def buildingActivity?(model = nil)
|
|
740
|
+
lgs = @feedback[:logs]
|
|
741
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
742
|
+
cl = OpenStudio::Model::Model
|
|
743
|
+
|
|
744
|
+
unless model.is_a?(OpenStudio::Model::Model)
|
|
745
|
+
lgs << "Invalid or empty OpenStudio model (#{mth})"
|
|
746
|
+
return false
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
tag = "btap_building_activity"
|
|
750
|
+
bldg = model.getBuilding
|
|
751
|
+
activity = bldg.additionalProperties.getFeatureAsString(tag)
|
|
752
|
+
return false if activity.empty?
|
|
753
|
+
|
|
754
|
+
activity = activity.get.downcase
|
|
755
|
+
return false unless data[:bldg][:activities].include?(activity)
|
|
756
|
+
|
|
757
|
+
true
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
##
|
|
761
|
+
# Collects list of neighbouring (side-by-side), non-ancillary spaces.
|
|
762
|
+
# Here, non-ancillary spaces include ancillary spaces that have valid
|
|
763
|
+
# assigned schedule sets.
|
|
764
|
+
#
|
|
765
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
766
|
+
#
|
|
767
|
+
# @return [Array] neighbouring (non-ancillary) spaces
|
|
768
|
+
def neighbours(space = nil)
|
|
769
|
+
lgs = @feedback[:logs]
|
|
770
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
771
|
+
cl = OpenStudio::Model::Space
|
|
772
|
+
|
|
773
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
774
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
775
|
+
return {}
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
nghbours = []
|
|
779
|
+
|
|
780
|
+
space.surfaces.each do |s|
|
|
781
|
+
next unless s.surfaceType.downcase == "wall"
|
|
782
|
+
|
|
783
|
+
voisin = s.adjacentSurface
|
|
784
|
+
next if voisin.empty?
|
|
785
|
+
|
|
786
|
+
espace = voisin.get.space
|
|
787
|
+
next if espace.empty?
|
|
788
|
+
|
|
789
|
+
espace = espace.get
|
|
790
|
+
next if espace == space
|
|
791
|
+
next if nghbours.include?(espace)
|
|
792
|
+
next unless @activities.key?(espace)
|
|
793
|
+
next unless @activities[espace][:schedule] != "*"
|
|
794
|
+
|
|
795
|
+
nghbours << espace
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
nghbours
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
##
|
|
802
|
+
# Sets schedules to auxiliary spaces.
|
|
803
|
+
#
|
|
804
|
+
# @param uset [Boolean] whether user has explicitly set a building activity.
|
|
805
|
+
#
|
|
806
|
+
# @return [Boolean] true if successful
|
|
807
|
+
def assignAuxiliarySchedules(uset = false)
|
|
808
|
+
lgs = @feedback[:logs]
|
|
809
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
810
|
+
bkup = "a"
|
|
811
|
+
uset = false unless [true, false].include?(uset)
|
|
812
|
+
|
|
813
|
+
if @@data[:bldg][:activity].key?(@activity)
|
|
814
|
+
bkup = @@data[:bldg][:activity][@activity][:schedule]
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
# Loop through auxiliary spaces (largest to smallest in floor area).
|
|
818
|
+
@activities.sort_by { |space, v| v[:m2] }.reverse.each do |space, v|
|
|
819
|
+
id = space.nameString
|
|
820
|
+
sch = self.schedule(space)
|
|
821
|
+
next unless self.auxiliary?(v[:keyword])
|
|
822
|
+
|
|
823
|
+
v[:schedule] = uset ? bkup : sch.delete("*")
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
true
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
##
|
|
830
|
+
# Sets schedules to ancillary spaces.
|
|
831
|
+
#
|
|
832
|
+
# @return [Boolean] true if successful
|
|
833
|
+
def assignAncillarySchedules
|
|
834
|
+
lgs = @feedback[:logs]
|
|
835
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
836
|
+
bkup = "a"
|
|
837
|
+
|
|
838
|
+
if @@data[:bldg][:activity].key?(@activity)
|
|
839
|
+
bkup = @@data[:bldg][:activity][@activity][:schedule]
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
# Loop through ancillary spaces (largest to smallest in floor area).
|
|
843
|
+
@activities.sort_by { |space, v| v[:m2] }.reverse.each do |space, v|
|
|
844
|
+
id = space.nameString
|
|
845
|
+
next unless self.ancillary?(v[:keyword])
|
|
846
|
+
|
|
847
|
+
# Retrieve each space's non-ancillary neighbours.
|
|
848
|
+
schedules = {}
|
|
849
|
+
schedule = bkup
|
|
850
|
+
|
|
851
|
+
self.neighbours(space).each do |nghbour|
|
|
852
|
+
next unless @activities.key?(nghbour)
|
|
853
|
+
|
|
854
|
+
sched = @activities[nghbour][:schedule]
|
|
855
|
+
m2 = @activities[nghbour][:m2]
|
|
856
|
+
|
|
857
|
+
schedules[sched] = 0 unless schedules.key?(sched)
|
|
858
|
+
schedules[sched] += m2
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
if schedules.empty?
|
|
862
|
+
# Assign common building schedule if no non-ancillary adjacent spaces.
|
|
863
|
+
lgs << "Assigning BUILDING schedule #{bkup} for #{id} (#{mth})"
|
|
864
|
+
v[:schedule] = bkup
|
|
865
|
+
else
|
|
866
|
+
v[:schedule] = schedules.sort_by { |sched, m2| m2 }.reverse.first.first
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
# Forcing schedule set 'J' for ancillary spaces in:
|
|
870
|
+
# - short-term accomodation (e.g. hotels, firestation quarters)
|
|
871
|
+
# - housing (MURBs, dormitories)
|
|
872
|
+
v[:schedule] = "j" if ["f", "g"].include?(v[:schedule])
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
true
|
|
876
|
+
end
|
|
877
|
+
|
|
878
|
+
##
|
|
879
|
+
# Returns a space's BTAP::Activity keyword, e.g. "corridor::hospital".
|
|
880
|
+
#
|
|
881
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
882
|
+
#
|
|
883
|
+
# @return [String] a space's BTAP::Activity keyword - check logs if empty
|
|
884
|
+
def keyword(space = nil)
|
|
885
|
+
lgs = @feedback[:logs]
|
|
886
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
887
|
+
cl = OpenStudio::Model::Space
|
|
888
|
+
|
|
889
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
890
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
891
|
+
return ""
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
unless @activities.key?(space)
|
|
895
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
896
|
+
return ""
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
@activities[space][:keyword]
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
##
|
|
903
|
+
# Returns a space's activity, e.g. "corridor" in "corridor::hospital".
|
|
904
|
+
#
|
|
905
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
906
|
+
#
|
|
907
|
+
# @return [String] a space's activity - check logs if empty
|
|
908
|
+
def act(space = nil)
|
|
909
|
+
lgs = @feedback[:logs]
|
|
910
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
911
|
+
cl = OpenStudio::Model::Space
|
|
912
|
+
|
|
913
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
914
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
915
|
+
return ""
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
unless @activities.key?(space)
|
|
919
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
920
|
+
return ""
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
@activities[space][:activity]
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
##
|
|
927
|
+
# Returns a space's building type, e.g. "hospital" in "corridor::hospital".
|
|
928
|
+
#
|
|
929
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
930
|
+
#
|
|
931
|
+
# @return [String] a space's building type - check logs if empty
|
|
932
|
+
def bldg(space = nil)
|
|
933
|
+
lgs = @feedback[:logs]
|
|
934
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
935
|
+
cl = OpenStudio::Model::Space
|
|
936
|
+
|
|
937
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
938
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
939
|
+
return ""
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
unless @activities.key?(space)
|
|
943
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
944
|
+
return ""
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
@activities[space][:bldgtype]
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
##
|
|
951
|
+
# Returns a space's floor area (m2), factoring a space's multiplier.
|
|
952
|
+
#
|
|
953
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
954
|
+
#
|
|
955
|
+
# @return [Float] space's floor area - check logs if 0 m2
|
|
956
|
+
def m2(space = nil)
|
|
957
|
+
lgs = @feedback[:logs]
|
|
958
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
959
|
+
cl = OpenStudio::Model::Space
|
|
960
|
+
|
|
961
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
962
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
963
|
+
return 0.0
|
|
964
|
+
end
|
|
965
|
+
|
|
966
|
+
unless @activities.key?(space)
|
|
967
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
968
|
+
return 0.0
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
@activities[space][:m2]
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
##
|
|
975
|
+
# Returns a space's occupant density (m2/occupant).
|
|
976
|
+
#
|
|
977
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
978
|
+
#
|
|
979
|
+
# @return [Float] space's occupant density - check logs if 0 m2/occupant
|
|
980
|
+
def density(space = nil)
|
|
981
|
+
lgs = @feedback[:logs]
|
|
982
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
983
|
+
cl = OpenStudio::Model::Space
|
|
984
|
+
|
|
985
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
986
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
987
|
+
return 0.0
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
unless @activities.key?(space)
|
|
991
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
992
|
+
return 0.0
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
@activities[space][:density]
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
##
|
|
999
|
+
# Returns a space's peak receptacle load (W/m2).
|
|
1000
|
+
#
|
|
1001
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
1002
|
+
#
|
|
1003
|
+
# @return [Float] space's peak equipment load - check logs if 0 W/m2
|
|
1004
|
+
def eqpWm2(space = nil)
|
|
1005
|
+
lgs = @feedback[:logs]
|
|
1006
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1007
|
+
cl = OpenStudio::Model::Space
|
|
1008
|
+
|
|
1009
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1010
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1011
|
+
return 0.0
|
|
1012
|
+
end
|
|
1013
|
+
|
|
1014
|
+
unless @activities.key?(space)
|
|
1015
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1016
|
+
return 0.0
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
@activities[space][:eqpload]
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
##
|
|
1023
|
+
# Returns a space's peak service water heating load (W/m2).
|
|
1024
|
+
#
|
|
1025
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
1026
|
+
#
|
|
1027
|
+
# @return [Float] space's peak SWH load - check logs if 0 W/m2
|
|
1028
|
+
def swhWm2(space = nil)
|
|
1029
|
+
lgs = @feedback[:logs]
|
|
1030
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1031
|
+
cl = OpenStudio::Model::Space
|
|
1032
|
+
|
|
1033
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1034
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1035
|
+
return 0.0
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
unless @activities.key?(space)
|
|
1039
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1040
|
+
return 0.0
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
@activities[space][:swhload]
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
##
|
|
1047
|
+
# Returns a space's (NECB-related) schedule set character, e.g. "a".
|
|
1048
|
+
#
|
|
1049
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
1050
|
+
#
|
|
1051
|
+
# @return [String] schedule set. Check logs if empty string.
|
|
1052
|
+
def schedule(space = nil)
|
|
1053
|
+
lgs = @feedback[:logs]
|
|
1054
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1055
|
+
cl = OpenStudio::Model::Space
|
|
1056
|
+
|
|
1057
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1058
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1059
|
+
return ""
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
unless @activities.key?(space)
|
|
1063
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1064
|
+
return ""
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
@activities[space][:schedule]
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
##
|
|
1071
|
+
# Validates whether a space is targeted for occupancy-sensing lighting
|
|
1072
|
+
# control, per NECB2011.
|
|
1073
|
+
#
|
|
1074
|
+
# @param space [OpenStudio::Model::Space] an OpenStudio space
|
|
1075
|
+
#
|
|
1076
|
+
# @return [Boolean] true if occsensing
|
|
1077
|
+
def occsensing?(space = nil)
|
|
1078
|
+
lgs = @feedback[:logs]
|
|
1079
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1080
|
+
cl = OpenStudio::Model::Space
|
|
1081
|
+
|
|
1082
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1083
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1084
|
+
return false
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
unless @activities.key?(space)
|
|
1088
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1089
|
+
return false
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
activity = @activities[space][:keyword]
|
|
1093
|
+
area = space.floorArea
|
|
1094
|
+
return true if activity == "classroom::common"
|
|
1095
|
+
return true if activity == "classroom::penitentiary"
|
|
1096
|
+
return true if activity == "meeting::common"
|
|
1097
|
+
return true if activity == "lounge::common"
|
|
1098
|
+
return true if activity == "lounge::health"
|
|
1099
|
+
return true if activity == "storage::common" && area.round < 100
|
|
1100
|
+
return true if activity == "supplies::health" && area.round < 100
|
|
1101
|
+
return true if activity == "copiers::common"
|
|
1102
|
+
return true if activity == "office::common" && area.round < 25
|
|
1103
|
+
return true if activity == "washroom::common"
|
|
1104
|
+
return true if activity == "dressing::theatre"
|
|
1105
|
+
return true if activity == "dressing::retail"
|
|
1106
|
+
return true if activity == "locker::common"
|
|
1107
|
+
|
|
1108
|
+
false
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
##
|
|
1112
|
+
# Returns a space's "factor for occupancy control" of lighting (Focc), per
|
|
1113
|
+
# NECB 4.3.2.10.1 (2015-2025).
|
|
1114
|
+
#
|
|
1115
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
1116
|
+
#
|
|
1117
|
+
# @return [Float] space's Focc of lighting - 1.0 if N/A.
|
|
1118
|
+
def fOCC(space = nil)
|
|
1119
|
+
lgs = @feedback[:logs]
|
|
1120
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1121
|
+
cl = OpenStudio::Model::Space
|
|
1122
|
+
|
|
1123
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1124
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1125
|
+
return 1.0
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
unless @activities.key?(space)
|
|
1129
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1130
|
+
return 1.0
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
activity = @activities[space][:keyword]
|
|
1134
|
+
|
|
1135
|
+
# Focc = 1 - Ca x Cocc, where:
|
|
1136
|
+
# Ca = factor to account for the relative absence of occupants
|
|
1137
|
+
# Cocc = factor to account for the occupancy-sensing mechanism
|
|
1138
|
+
cA = case activity
|
|
1139
|
+
when "audience::convention" then 0.2
|
|
1140
|
+
when "audience::religious" then 0.3
|
|
1141
|
+
when "classroom::common" then 0.5
|
|
1142
|
+
when "classroom::penitentiary" then 0.5
|
|
1143
|
+
when "computer::common" then 0.7
|
|
1144
|
+
when "server::common" then 0.7
|
|
1145
|
+
when "meeting::common" then 0.5
|
|
1146
|
+
when "copiers::common" then 0.2
|
|
1147
|
+
when "tribunal::court" then 0.2
|
|
1148
|
+
when "dressing::theatre" then 0.4
|
|
1149
|
+
when "mechanical::common" then 0.9
|
|
1150
|
+
when "emergency::common" then 0.5
|
|
1151
|
+
when "teachinglab::common" then 0.4
|
|
1152
|
+
when "locker::common" then 0.5
|
|
1153
|
+
when "openplan::common" then 0.2
|
|
1154
|
+
when "office::common" then 0.3
|
|
1155
|
+
when "garage::parking" then 0.4
|
|
1156
|
+
when "storage::common" then 0.6
|
|
1157
|
+
when "washroom::common" then 0.5
|
|
1158
|
+
when "supplies::health" then 0.5
|
|
1159
|
+
when "exam::health" then 0.3
|
|
1160
|
+
when "operating::health" then 0.1
|
|
1161
|
+
when "patient::health" then 0.1
|
|
1162
|
+
when "therapy::health" then 0.2
|
|
1163
|
+
when "equipment::manufacturing" then 0.2
|
|
1164
|
+
when "restoration::museum" then 0.3
|
|
1165
|
+
when "exhibit::museum" then 0.2
|
|
1166
|
+
when "refectory::religious" then 0.3
|
|
1167
|
+
when "pulpit::religious" then 0.1
|
|
1168
|
+
when "dressing::retail" then 0.4
|
|
1169
|
+
when "chapel::religious" then 0.5
|
|
1170
|
+
when "recreation::common" then 0.2
|
|
1171
|
+
when "bulk::warehouse" then 0.5
|
|
1172
|
+
when "fine::warehouse" then 0.5
|
|
1173
|
+
else 0.0
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1176
|
+
return 1.0 if cA.round(1) == 0.0
|
|
1177
|
+
|
|
1178
|
+
# NECB 2025 Table 4.3.2.10.-B : Cocc
|
|
1179
|
+
# _____________________________________________________________ ____
|
|
1180
|
+
# automatic FULL OFF (FULL ON) 0.67
|
|
1181
|
+
# automatic FULL OFF (manual ON or automatic PARTIAL ON) 0.75
|
|
1182
|
+
# automatic PARTIAL OFF (manual ON) 0.34
|
|
1183
|
+
# manual (ON/OFF or bi-level) – enclosed office less than 25 m2 0.30
|
|
1184
|
+
# manual – all other spaces 0.10
|
|
1185
|
+
# none 0.00
|
|
1186
|
+
#
|
|
1187
|
+
# The conditional application of lighting controls is often subject to
|
|
1188
|
+
# professional judgment (as described in the NECB). Automating their
|
|
1189
|
+
# assignment (e.g. Cocc within BTAP) becomes particularly challenging.
|
|
1190
|
+
#
|
|
1191
|
+
# The following are tentative postulates governing the automated
|
|
1192
|
+
# application of Cocc - needs a deeper dive, @todo:
|
|
1193
|
+
#
|
|
1194
|
+
# - almost all spaces require manual ON
|
|
1195
|
+
# - almost all spaces require automated or scheduled OFF (only)
|
|
1196
|
+
# - so by default, spaces with Ca > 0 (see above): Cocc of 0.75
|
|
1197
|
+
#
|
|
1198
|
+
# - spaces with automated PARTIAL OFF control have a Cocc of 0.34
|
|
1199
|
+
#
|
|
1200
|
+
# - all other (unlisted) spaces: Cocc of 0.10.
|
|
1201
|
+
cOCC = case activity
|
|
1202
|
+
when "audience::convention" then 0.75
|
|
1203
|
+
when "audience::religious" then 0.75
|
|
1204
|
+
when "classroom::common" then 0.75
|
|
1205
|
+
when "classroom::penitentiary" then 0.75
|
|
1206
|
+
when "computer::common" then 0.75
|
|
1207
|
+
when "server::common" then 0.75
|
|
1208
|
+
when "meeting::common" then 0.75
|
|
1209
|
+
when "copiers::common" then 0.75
|
|
1210
|
+
when "tribunal::court" then 0.75
|
|
1211
|
+
when "dressing::theatre" then 0.75
|
|
1212
|
+
when "mechanical::common" then 0.75
|
|
1213
|
+
when "emergency::common" then 0.75
|
|
1214
|
+
when "teachinglab::common" then 0.34 #
|
|
1215
|
+
when "locker::common" then 0.75
|
|
1216
|
+
when "openplan::common" then 0.75
|
|
1217
|
+
when "office::common" then 0.75
|
|
1218
|
+
when "garage::parking" then 0.34 #
|
|
1219
|
+
when "storage::common" then 0.75
|
|
1220
|
+
when "washroom::common" then 0.75
|
|
1221
|
+
when "supplies::health" then 0.75
|
|
1222
|
+
when "exam::health" then 0.75
|
|
1223
|
+
when "operating::health" then 0.75
|
|
1224
|
+
when "patient::health" then 0.75
|
|
1225
|
+
when "therapy::health" then 0.75
|
|
1226
|
+
when "equipment::manufacturing" then 0.75
|
|
1227
|
+
when "restoration::museum" then 0.75
|
|
1228
|
+
when "exhibit::museum" then 0.75
|
|
1229
|
+
when "refectory::religious" then 0.75
|
|
1230
|
+
when "pulpit::religious" then 0.75
|
|
1231
|
+
when "dressing::retail" then 0.75
|
|
1232
|
+
when "chapel::religious" then 0.75
|
|
1233
|
+
when "recreation::common" then 0.75
|
|
1234
|
+
when "bulk::warehouse" then 0.34 #
|
|
1235
|
+
when "fine::warehouse" then 0.34 #
|
|
1236
|
+
else 0.10
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
# Reset cOCC if small enclosed offices.
|
|
1240
|
+
cOCC = 0.30 if activity == "office::common" && space.floorArea < 25
|
|
1241
|
+
|
|
1242
|
+
1.0 - cA * cOCC
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
##
|
|
1246
|
+
# Returns a space's "factor for personal control" of lighting (Fpers),
|
|
1247
|
+
# per NECB 4.3.2.10.2 (2015-2025).
|
|
1248
|
+
#
|
|
1249
|
+
# @param space [OpenStudio::Model::Space] a space
|
|
1250
|
+
#
|
|
1251
|
+
# @return [Float] space's Fpers of lighting - 1.0 if N/A.
|
|
1252
|
+
def fPERS(space = nil)
|
|
1253
|
+
lgs = @feedback[:logs]
|
|
1254
|
+
mth = "BTAP::Activity::#{__callee__}"
|
|
1255
|
+
cl = OpenStudio::Model::Space
|
|
1256
|
+
|
|
1257
|
+
unless space.is_a?(OpenStudio::Model::Space)
|
|
1258
|
+
lgs << "Invalid or empty OpenStudio space (#{mth})"
|
|
1259
|
+
return 1.0
|
|
1260
|
+
end
|
|
1261
|
+
|
|
1262
|
+
unless @activities.key?(space)
|
|
1263
|
+
lgs << "Unlisted space #{space.nameString} (#{mth})"
|
|
1264
|
+
return 1.0
|
|
1265
|
+
end
|
|
1266
|
+
|
|
1267
|
+
activity = @activities[space][:keyword]
|
|
1268
|
+
|
|
1269
|
+
return 0.9 if activity == "teachinglab::common"
|
|
1270
|
+
return 0.9 if activity == "openplan::common"
|
|
1271
|
+
return 0.9 if activity == "office::common"
|
|
1272
|
+
return 0.9 if activity == "patient::health"
|
|
1273
|
+
|
|
1274
|
+
1.0
|
|
1275
|
+
end
|
|
479
1276
|
end
|
|
480
1277
|
end
|