openstudio-common-measures 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/Rakefile +3 -0
  4. data/lib/measures/ChangeBuildingLocation/measure.xml +11 -11
  5. data/lib/measures/ExportScheduleCSV/measure.rb +1 -1
  6. data/lib/measures/ExportScheduleCSV/measure.xml +16 -15
  7. data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.xml +7 -6
  8. data/lib/measures/MeterFlodPlot/measure.rb +1 -1
  9. data/lib/measures/MeterFlodPlot/measure.xml +16 -15
  10. data/lib/measures/ReportModelChanges/measure.xml +2 -2
  11. data/lib/measures/RunPeriodMultiple/measure.xml +12 -11
  12. data/lib/measures/ServerDirectoryCleanup/README.md +97 -3
  13. data/lib/measures/ServerDirectoryCleanup/measure.rb +1 -1
  14. data/lib/measures/ServerDirectoryCleanup/measure.xml +10 -59
  15. data/lib/measures/UnmetLoadHoursTroubleshooting/README.md +9 -3
  16. data/lib/measures/UnmetLoadHoursTroubleshooting/measure.rb +1 -1
  17. data/lib/measures/UnmetLoadHoursTroubleshooting/measure.xml +66 -17
  18. data/lib/measures/VentilationQAQC/README.md +9 -3
  19. data/lib/measures/VentilationQAQC/measure.rb +52 -45
  20. data/lib/measures/VentilationQAQC/measure.xml +25 -30
  21. data/lib/measures/ZoneReport/README.md +2 -2
  22. data/lib/measures/ZoneReport/measure.rb +1 -1
  23. data/lib/measures/ZoneReport/measure.xml +10 -11
  24. data/lib/measures/add_ems_to_control_ev_charging/LICENSE.MD.txt +15 -0
  25. data/lib/measures/{AddDaylightSensors → add_ems_to_control_ev_charging}/LICENSE.md +0 -0
  26. data/lib/measures/add_ems_to_control_ev_charging/ReadMe.MD +29 -0
  27. data/lib/measures/add_ems_to_control_ev_charging/measure.rb +288 -0
  28. data/lib/measures/add_ems_to_control_ev_charging/measure.xml +87 -0
  29. data/lib/measures/add_ev_load/LICENSE.MD.txt +15 -0
  30. data/lib/measures/{EnableDemandControlledVentilation → add_ev_load}/LICENSE.md +0 -0
  31. data/lib/measures/add_ev_load/ReadMe.MD +34 -0
  32. data/lib/measures/add_ev_load/measure.rb +328 -0
  33. data/lib/measures/add_ev_load/measure.xml +153 -0
  34. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/PSN_BuildingKey.csv +104 -0
  35. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/PSN_BuildingKey_v2.csv +104 -0
  36. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex1.csv +96 -0
  37. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex2.csv +96 -0
  38. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex3.csv +96 -0
  39. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex1.csv +96 -0
  40. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex2.csv +96 -0
  41. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex3.csv +96 -0
  42. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex1.csv +96 -0
  43. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex2.csv +96 -0
  44. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex3.csv +96 -0
  45. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex1.csv +96 -0
  46. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex2.csv +96 -0
  47. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex3.csv +96 -0
  48. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex1.csv +96 -0
  49. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex2.csv +96 -0
  50. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex3.csv +96 -0
  51. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex1.csv +96 -0
  52. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex2.csv +96 -0
  53. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex3.csv +96 -0
  54. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex1.csv +96 -0
  55. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex2.csv +96 -0
  56. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex3.csv +96 -0
  57. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex1.csv +96 -0
  58. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex2.csv +96 -0
  59. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex3.csv +96 -0
  60. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex1.csv +96 -0
  61. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex2.csv +96 -0
  62. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex3.csv +96 -0
  63. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Saturday.csv +96 -0
  64. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Sunday.csv +96 -0
  65. data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Weekday.csv +96 -0
  66. data/lib/measures/envelope_and_internal_load_breakdown/README.md +4 -3
  67. data/lib/measures/envelope_and_internal_load_breakdown/measure.rb +7 -4
  68. data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +16 -17
  69. data/lib/measures/envelope_and_internal_load_breakdown/resources/report.html.erb +1 -0
  70. data/lib/measures/example_report/README.md +27 -5
  71. data/lib/measures/example_report/measure.rb +7 -4
  72. data/lib/measures/example_report/measure.xml +16 -29
  73. data/lib/measures/example_report/resources/report.html.erb +1 -0
  74. data/lib/measures/gem_env_report/measure.xml +1 -1
  75. data/lib/measures/generic_qaqc/README.md +187 -5
  76. data/lib/measures/generic_qaqc/measure.rb +1 -1
  77. data/lib/measures/generic_qaqc/measure.xml +15 -85
  78. data/lib/measures/generic_qaqc/resources/report.html.erb +1 -0
  79. data/lib/measures/hvac_psychrometric_chart/README.md +11 -5
  80. data/lib/measures/hvac_psychrometric_chart/measure.rb +1 -1
  81. data/lib/measures/hvac_psychrometric_chart/measure.xml +13 -18
  82. data/lib/measures/hvac_psychrometric_chart/resources/report.html.erb +1 -0
  83. data/lib/measures/inject_idf_objects/measure.xml +25 -24
  84. data/lib/measures/openstudio_results/README.md +195 -5
  85. data/lib/measures/openstudio_results/measure.rb +2 -2
  86. data/lib/measures/openstudio_results/measure.xml +30 -154
  87. data/lib/measures/openstudio_results/resources/report.html.erb +1 -0
  88. data/lib/measures/set_run_period/measure.xml +2 -2
  89. data/lib/measures/{EnableEconomizerControl → view_data}/LICENSE.md +0 -0
  90. data/lib/measures/view_data/README.md +64 -0
  91. data/lib/measures/{AddDaylightSensors → view_data}/README.md.erb +0 -0
  92. data/lib/measures/view_data/measure.rb +454 -0
  93. data/lib/measures/view_data/measure.xml +159 -0
  94. data/lib/measures/view_data/resources/report.html.in +2881 -0
  95. data/lib/measures/view_data/resources/va3c.rb +1021 -0
  96. data/lib/measures/{ImproveFanBeltEfficiency → view_model}/LICENSE.md +0 -0
  97. data/lib/measures/view_model/README.md +26 -0
  98. data/lib/measures/{EnableDemandControlledVentilation → view_model}/README.md.erb +0 -0
  99. data/lib/measures/view_model/measure.rb +146 -0
  100. data/lib/measures/view_model/measure.xml +98 -0
  101. data/lib/measures/view_model/resources/report.html.in +2881 -0
  102. data/lib/measures/view_model/resources/va3c.rb +1021 -0
  103. data/lib/openstudio/common_measures/version.rb +1 -1
  104. data/openstudio-common-measures.gemspec +1 -1
  105. metadata +61 -71
  106. data/lib/measures/AddDaylightSensors/README.md +0 -136
  107. data/lib/measures/AddDaylightSensors/measure.rb +0 -521
  108. data/lib/measures/AddDaylightSensors/measure.xml +0 -233
  109. data/lib/measures/EnableDemandControlledVentilation/README.md +0 -32
  110. data/lib/measures/EnableDemandControlledVentilation/measure.rb +0 -154
  111. data/lib/measures/EnableDemandControlledVentilation/measure.xml +0 -99
  112. data/lib/measures/EnableEconomizerControl/README.md +0 -48
  113. data/lib/measures/EnableEconomizerControl/README.md.erb +0 -42
  114. data/lib/measures/EnableEconomizerControl/measure.rb +0 -172
  115. data/lib/measures/EnableEconomizerControl/measure.xml +0 -124
  116. data/lib/measures/ImproveFanBeltEfficiency/README.md +0 -104
  117. data/lib/measures/ImproveFanBeltEfficiency/README.md.erb +0 -42
  118. data/lib/measures/ImproveFanBeltEfficiency/measure.rb +0 -366
  119. data/lib/measures/ImproveFanBeltEfficiency/measure.xml +0 -185
  120. data/lib/measures/ImproveMotorEfficiency/LICENSE.md +0 -27
  121. data/lib/measures/ImproveMotorEfficiency/README.md +0 -104
  122. data/lib/measures/ImproveMotorEfficiency/README.md.erb +0 -42
  123. data/lib/measures/ImproveMotorEfficiency/measure.rb +0 -365
  124. data/lib/measures/ImproveMotorEfficiency/measure.xml +0 -182
  125. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/LICENSE.md +0 -27
  126. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/README.md +0 -64
  127. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/README.md.erb +0 -42
  128. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.rb +0 -422
  129. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.xml +0 -150
  130. data/lib/measures/IncreaseInsulationRValueForRoofs/LICENSE.md +0 -27
  131. data/lib/measures/IncreaseInsulationRValueForRoofs/README.md +0 -64
  132. data/lib/measures/IncreaseInsulationRValueForRoofs/README.md.erb +0 -42
  133. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.rb +0 -422
  134. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.xml +0 -143
  135. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/LICENSE.md +0 -27
  136. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/README.md +0 -97
  137. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/README.md.erb +0 -42
  138. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.rb +0 -450
  139. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.xml +0 -186
  140. data/lib/measures/ReduceLightingLoadsByPercentage/LICENSE.md +0 -27
  141. data/lib/measures/ReduceLightingLoadsByPercentage/README.md +0 -96
  142. data/lib/measures/ReduceLightingLoadsByPercentage/README.md.erb +0 -42
  143. data/lib/measures/ReduceLightingLoadsByPercentage/measure.rb +0 -513
  144. data/lib/measures/ReduceLightingLoadsByPercentage/measure.xml +0 -191
  145. data/lib/measures/ReduceSpaceInfiltrationByPercentage/LICENSE.md +0 -27
  146. data/lib/measures/ReduceSpaceInfiltrationByPercentage/README.md +0 -104
  147. data/lib/measures/ReduceSpaceInfiltrationByPercentage/README.md.erb +0 -42
  148. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.rb +0 -349
  149. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.xml +0 -181
  150. data/lib/measures/ReduceVentilationByPercentage/LICENSE.md +0 -27
  151. data/lib/measures/ReduceVentilationByPercentage/README.md +0 -40
  152. data/lib/measures/ReduceVentilationByPercentage/README.md.erb +0 -42
  153. data/lib/measures/ReduceVentilationByPercentage/measure.rb +0 -291
  154. data/lib/measures/ReduceVentilationByPercentage/measure.xml +0 -96
  155. data/lib/measures/VentilationQAQC/ExampleModel.osm +0 -28468
  156. data/lib/measures/create_variable_speed_rtu/LICENSE.md +0 -27
  157. data/lib/measures/create_variable_speed_rtu/README.md +0 -120
  158. data/lib/measures/create_variable_speed_rtu/README.md.erb +0 -42
  159. data/lib/measures/create_variable_speed_rtu/measure.rb +0 -539
  160. data/lib/measures/create_variable_speed_rtu/measure.xml +0 -207
  161. data/lib/measures/radiant_slab_with_doas/LICENSE.md +0 -27
  162. data/lib/measures/radiant_slab_with_doas/README.md +0 -156
  163. data/lib/measures/radiant_slab_with_doas/README.md.erb +0 -42
  164. data/lib/measures/radiant_slab_with_doas/measure.rb +0 -403
  165. data/lib/measures/radiant_slab_with_doas/measure.xml +0 -345
@@ -0,0 +1,87 @@
1
+ <?xml version="1.0"?>
2
+ <measure>
3
+ <schema_version>3.0</schema_version>
4
+ <name>add_ems_to_control_ev_charging</name>
5
+ <uid>df97997f-d02a-4e35-af7a-5aed16cb5772</uid>
6
+ <version_id>0ad18ca6-32ff-4264-9451-36a1bcb0aadf</version_id>
7
+ <version_modified>20200901T153152Z</version_modified>
8
+ <xml_checksum>976EB6EB</xml_checksum>
9
+ <class_name>AddEMSToControlEVCharging</class_name>
10
+ <display_name>Add EMS to Control EV Charging</display_name>
11
+ <description>This measure implements a control system to curtail an electric vehicle (EV) charging load to better align EV charging with expected energy production from a solar PV system.</description>
12
+ <modeler_description>This measure uses EnergyPlus' Energy Management System to control an electric vehicle (EV) charging load to better align charging power draw with expected energy production from solar PV. There must already be an EV charging load present in the model when this measure is applied, and the measure is configured based on the assumption of a typical office operating schedule.</modeler_description>
13
+ <arguments>
14
+ <argument>
15
+ <name>curtailment_frac</name>
16
+ <display_name>Fraction by Which to Curtail EV Charging During Load Shifting Events</display_name>
17
+ <type>Double</type>
18
+ <required>true</required>
19
+ <model_dependent>false</model_dependent>
20
+ <default_value>0.5</default_value>
21
+ </argument>
22
+ </arguments>
23
+ <outputs />
24
+ <provenances />
25
+ <tags>
26
+ <tag>Equipment.Equipment Controls</tag>
27
+ </tags>
28
+ <attributes>
29
+ <attribute>
30
+ <name>Measure Type</name>
31
+ <value>ModelMeasure</value>
32
+ <datatype>string</datatype>
33
+ </attribute>
34
+ <attribute>
35
+ <name>Intended Software Tool</name>
36
+ <value>Apply Measure Now</value>
37
+ <datatype>string</datatype>
38
+ </attribute>
39
+ <attribute>
40
+ <name>Intended Software Tool</name>
41
+ <value>OpenStudio Application</value>
42
+ <datatype>string</datatype>
43
+ </attribute>
44
+ <attribute>
45
+ <name>Intended Software Tool</name>
46
+ <value>Parametric Analysis Tool</value>
47
+ <datatype>string</datatype>
48
+ </attribute>
49
+ </attributes>
50
+ <files>
51
+ <file>
52
+ <filename>example_model.osm</filename>
53
+ <filetype>osm</filetype>
54
+ <usage_type>test</usage_type>
55
+ <checksum>E925F127</checksum>
56
+ </file>
57
+ <file>
58
+ <filename>README.md</filename>
59
+ <filetype>md</filetype>
60
+ <usage_type>readme</usage_type>
61
+ <checksum>70CA2C6E</checksum>
62
+ </file>
63
+ <file>
64
+ <filename>add_ems_to_control_ev_charging_test.rb</filename>
65
+ <filetype>rb</filetype>
66
+ <usage_type>test</usage_type>
67
+ <checksum>B6C25840</checksum>
68
+ </file>
69
+ <file>
70
+ <version>
71
+ <software_program>OpenStudio</software_program>
72
+ <identifier>2.5.1</identifier>
73
+ <min_compatible>2.5.1</min_compatible>
74
+ </version>
75
+ <filename>measure.rb</filename>
76
+ <filetype>rb</filetype>
77
+ <usage_type>script</usage_type>
78
+ <checksum>31F0CB5F</checksum>
79
+ </file>
80
+ <file>
81
+ <filename>LICENSE.md</filename>
82
+ <filetype>md</filetype>
83
+ <usage_type>license</usage_type>
84
+ <checksum>E0468DD6</checksum>
85
+ </file>
86
+ </files>
87
+ </measure>
@@ -0,0 +1,15 @@
1
+
2
+
3
+ OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
+
7
+ (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
+
9
+ (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+
11
+ (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission from the respective party.
12
+
13
+ (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior written permission from Alliance for Sustainable Energy, LLC.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: "ReadMe"
3
+ author: "Amy Allen"
4
+ date: "8/18/2020"
5
+ output: html_document
6
+ ---
7
+
8
+ ```{r setup, include=FALSE}
9
+ knitr::opts_chunk$set(echo = TRUE)
10
+ ```
11
+
12
+
13
+ ## Add EV Charging Load
14
+ ## Description
15
+ This measure adds an electric vehicle charging load, based on the load profiles developed by Wood et al. (2018), generated to reflect several different potential scenarios for EV charging behavior. The user can configure the magnitude of the load based on the proportion of vehicles at the site that are assumed to be EVs.
16
+
17
+ ## Modeler Description
18
+ The raw data used to generate the load profiles is saved in the "Resources" folder. The load that is added is an ExteriorFuelEquipment object. The load profiles generated by Wood et al. (2018) are based on an assumption of a 50% EV penetration rate.
19
+
20
+ ## Measure Type
21
+ ModelMeasure
22
+
23
+ ## Arguments
24
+ ## EV Percent
25
+ Name: EV Percent, Type: Double, Units: Percent , Required: true, Model Dependent: false. This argument is used to scale the load profiles generated by Wood et al. (2018). If not supplied by the user, the value defaults to 1%.
26
+
27
+ ## Charging Behavior
28
+ Name: Charging Behavior, Type: Choice (Business as Usual, Free Workplace Charging at Project Site, Free Workplace Charging Throughout Metropolitan Area), Units: None, Required: true, Model Dependent: false. Separate load profiles were generated by Wood et al. (2018) for each of these cases to reflect consumer behavior under differing availability of free EV charging.
29
+
30
+ ## Charge Station Type
31
+ Name: Charge Station Type, Type: Choice (Home, Typical Work, Typical Public), Units: None, Required: true, Model Dependent: false. This argument is used to select a subset of the profiles developed by Wood et al. (2018), which will be averaged to generate the profile for this particular building, based on its type.
32
+
33
+ ## Charge Delay
34
+ Name: Charge Delay, Type: Choice (Min Delay, Max Delay, Min Power) Units: None, Required: true, Model dependent: false. This argument is used to select a subset of profiles based on those generated by Wood et al. (2018), to reflect different approaches for control of EV charging. "Min delay" refers to a scenario in which the vehicle charging begins as soon as it is plugged in, "Max delay" refers to a control strategy that seeks to have the vehicle charged by the time the driver departs, and no sooner, and "Min power" seeks to minimize the power draw associated with charging.
@@ -0,0 +1,328 @@
1
+ # see the URL below for information on how to write OpenStudio measures
2
+ # http://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/
3
+ # *******************************************************************************
4
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
5
+ # All rights reserved.
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # (1) Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # (3) Neither the name of the copyright holder nor the names of any contributors
17
+ # may be used to endorse or promote products derived from this software without
18
+ # specific prior written permission from the respective party.
19
+ #
20
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
21
+ # of modifications or other derivative works may not use the "OpenStudio"
22
+ # trademark, "OS", "os", or any other confusingly similar designation without
23
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
26
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
29
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
30
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
32
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ # *******************************************************************************
37
+
38
+ require 'csv'
39
+ require 'matrix'
40
+ # start the measure
41
+ class AddEVLoad < OpenStudio::Measure::ModelMeasure
42
+ # human readable name
43
+ def name
44
+ return 'Add_EV_Load'
45
+ end
46
+
47
+ # human readable description
48
+ def description
49
+ return 'This measure adds a load associated with charging of electric vehicles (EVs) to a building in URBANopt. EV load profiles were generated in EVI-Pro for specific building types. This measure allows running of customized load profiles for buildings in the Pena Station Next project, and also for generating typical charging load profiles based on the location type (home, public, or office).'
50
+ end
51
+
52
+ # human readable description of modeling approach
53
+ def modeler_description
54
+ return 'This measure adds an EV charging load to a building model. Load profiles for EV charging were generated in EVI-Pro. Different options are available for charging control type and charging behavior.'
55
+ end
56
+
57
+ # Note: If a DC Fast Charger at the PSN site is the intended option, the charging behavior and control choices are ignored. Thus far, there is one load profile for a DC fast charger; not different ones for different bldgs.
58
+ # define the arguments that the user will input
59
+ def arguments(model)
60
+ args = OpenStudio::Measure::OSArgumentVector.new
61
+
62
+ # Make an argument for the charging flexibility options (workplace charging only).
63
+ charge_delay_chs = OpenStudio::StringVector.new
64
+ charge_delay_chs << 'Max Delay'
65
+ charge_delay_chs << 'Min Delay'
66
+ charge_delay_chs << 'Min Power'
67
+
68
+ delay_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('delay_type', charge_delay_chs, true)
69
+ delay_type.setDisplayName('Charging Flexibility Option')
70
+ delay_type.setDefaultValue('Min Delay')
71
+ args << delay_type
72
+
73
+ # Make an argument for the consumer charging behavior parameter.
74
+ consumer_charge_chs = OpenStudio::StringVector.new
75
+ consumer_charge_chs << 'Business as Usual'
76
+ consumer_charge_chs << 'Free Workplace Charging at Project Site'
77
+ consumer_charge_chs << 'Free Workplace Charging Across Metro Area'
78
+
79
+ charge_behavior = OpenStudio::Measure::OSArgument.makeChoiceArgument('charge_behavior', consumer_charge_chs, true)
80
+ charge_behavior.setDisplayName('Consumer Charging Behavior')
81
+ charge_behavior.setDefaultValue('Business as Usual')
82
+ args << charge_behavior
83
+
84
+ # Make a vector for the charging station type argument.
85
+ chg_station_type_chs = OpenStudio::StringVector.new
86
+ chg_station_type_chs << 'Typical Home'
87
+ chg_station_type_chs << 'Typical Public'
88
+ chg_station_type_chs << 'Typical Work'
89
+
90
+ # Make an argument for charging station type.
91
+ chg_station_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('chg_station_type', chg_station_type_chs, true)
92
+ chg_station_type.setDisplayName('Charging Station Type')
93
+ chg_station_type.setDefaultValue('Typical Public')
94
+ args << chg_station_type
95
+
96
+ # Make an argument for the % of vehicles parked at the building that are EVs.
97
+ ev_percent = OpenStudio::Measure::OSArgument.makeDoubleArgument('ev_percent', true)
98
+ ev_percent.setDisplayName('Percent of Vehicles Parked at Building That Are EVs')
99
+ ev_percent.setDefaultValue(1.0)
100
+ args << ev_percent
101
+
102
+ return args
103
+ end
104
+
105
+ # define what happens when the measure is run
106
+ def run(model, runner, user_arguments)
107
+ super(model, runner, user_arguments)
108
+
109
+ # Assign the user arguments to variables.
110
+ delay_type = runner.getStringArgumentValue('delay_type', user_arguments)
111
+ charge_behavior = runner.getStringArgumentValue('charge_behavior', user_arguments)
112
+ chg_station_type = runner.getStringArgumentValue('chg_station_type', user_arguments)
113
+ ev_percent = runner.getDoubleArgumentValue('ev_percent', user_arguments)
114
+
115
+ # use the built-in error checking
116
+ if !runner.validateUserArguments(arguments(model), user_arguments)
117
+ return false
118
+ end
119
+
120
+ if ev_percent < 0 || ev_percent > 100
121
+ runner.registerError('Percent of vehicles on site that are electric is outside of acceptable bounds. Please choose a value between 0 and 100.')
122
+ return false
123
+ end
124
+
125
+ # Set file name based on arguments selected and then choose the DOW within schedule selection.
126
+ # Set key based on user-selected charging behavior.
127
+ if charge_behavior == 'Business as Usual'
128
+ charge_key = 1
129
+ runner.registerInfo("charge key = #{charge_key}")
130
+ elsif charge_behavior == 'Free Workplace Charging at Project Site'
131
+ charge_key = 2
132
+ runner.registerInfo("charge key = #{charge_key}")
133
+ else
134
+ charge_key = 3
135
+ runner.registerInfo("charge key = #{charge_key}")
136
+ end
137
+
138
+ # Set key based on user-selected charging flexibility.
139
+ if delay_type == 'Min Delay'
140
+ flex_key = 1
141
+ runner.registerInfo("flex key = #{flex_key}")
142
+ elsif delay_type == 'Max Delay'
143
+ flex_key = 2
144
+ runner.registerInfo("flex key = #{flex_key}")
145
+ else
146
+ flex_key = 3
147
+ runner.registerInfo("flex key = #{flex_key}")
148
+ end
149
+
150
+ file_path = "#{__dir__}/resources/EV_Load_Profiles"
151
+
152
+ # Sets key based on charging station type, for general charging load profiles. Will use this to average columns appropriately.
153
+ if chg_station_type == 'Typical Home'
154
+ chg_station_key = 1
155
+ runner.registerInfo("charge station key = #{chg_station_key}")
156
+ elsif chg_station_type == 'Typical Work'
157
+ chg_station_key = 2
158
+ runner.registerInfo("charge station key = #{chg_station_key}")
159
+ elsif chg_station_type == 'Typical Public'
160
+ chg_station_key = 3
161
+ runner.registerInfo("charge station key = #{chg_station_key}")
162
+ end
163
+
164
+ # Creating a schedule:ruleset
165
+ ev_sch = OpenStudio::Model::ScheduleRuleset.new(model)
166
+ ev_sch.setName('EV Charging Power Draw')
167
+
168
+ # Create a schedule:ruleset for DC fast charging.
169
+ ev_sch_fast = OpenStudio::Model::ScheduleRuleset.new(model)
170
+ ev_sch_fast.setName('EV DC Fast Charging Power Draw')
171
+
172
+ # Create arrays of desired values
173
+ public_indices = [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 52, 53, 54, 57, 58, 60, 61, 62, 63, 64, 65, 81, 99, 100, 102]
174
+ work_indices = [7, 19, 20, 27, 28, 29, 30, 31, 32, 36, 37, 42, 43, 44, 46, 50, 51, 55, 69, 70, 71, 86, 88, 91, 92, 93]
175
+ home_indices = [15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 33, 34, 35, 38, 39, 40, 41, 45, 47, 48, 49, 56, 59, 66, 67, 68, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, 85, 87, 89, 90, 94, 95, 96, 97, 98, 101]
176
+
177
+ # The load profiles referenced were generated based on an assumption of 50% of passenger vehicles being EVs.
178
+ assumed_percent = 50
179
+
180
+ # Read in the three necessary files, for the typical PSN case (all PSN bldgs, including fast chargers).
181
+ # Read in wkday load profiles.
182
+ dow_key = 1
183
+ file_name = "chg#{charge_key}_dow#{dow_key}_flex#{flex_key}.csv"
184
+ wkday_load = CSV.read("#{file_path}/#{file_name}", headers: false, converters: :all)
185
+ wkday_load = wkday_load.to_a # Convert to an array.
186
+ wkday_load = wkday_load.transpose
187
+ # Read in Saturday load profiles.
188
+ dow_key = 2
189
+ file_name = "chg#{charge_key}_dow#{dow_key}_flex#{flex_key}.csv"
190
+ sat_load = CSV.read("#{file_path}/#{file_name}", headers: false, converters: :all)
191
+ sat_load = sat_load.to_a # Convert to an array.
192
+ sat_load = sat_load.transpose
193
+ # Read in Sunday load profiles.
194
+ dow_key = 3
195
+ file_name = "chg#{charge_key}_dow#{dow_key}_flex#{flex_key}.csv"
196
+ sun_load = CSV.read("#{file_path}/#{file_name}", headers: false, converters: :all)
197
+ sun_load = sun_load.to_a # Convert to an array.
198
+ sun_load = sun_load.transpose
199
+
200
+ # For non-PSN analysis, select which load profile is needed based on the charging station key.
201
+
202
+ if chg_station_key == 1
203
+ indices = home_indices
204
+ elsif chg_station_key == 2
205
+ indices = work_indices
206
+ elsif chg_station_key == 3
207
+ indices = public_indices
208
+ end
209
+
210
+ # Popualte the average weekday load for non PSN case. The load profiles used in this case are averaged based on the selected charging station type,(given the selected charging flexibility option and charging behavior option), and scaled for the percent of vehicles that are EVs.
211
+ if chg_station_type != 'Pena Station Next Analysis' && chg_station_type != 'Pena Station Next Analysis--DC Fast Charger'
212
+ wkday_load_sel = wkday_load.values_at(*indices)
213
+ avg_load_wkday = []
214
+ wkday_load_sel = wkday_load_sel.transpose
215
+ for i in 0..wkday_load[0].length - 1
216
+ avg_load_wkday[i] = (wkday_load_sel[i].reduce(0, :+) / wkday_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
217
+ end
218
+
219
+ wkday_max_load = avg_load_wkday.max
220
+
221
+ # Populate the average Saturday load.
222
+ sat_load_sel = sat_load.values_at(*indices)
223
+ avg_load_sat = []
224
+ sat_load_sel = sat_load_sel.transpose
225
+ for i in 0..sat_load[0].length - 1
226
+ avg_load_sat[i] = (sat_load_sel[i].reduce(0, :+) / sat_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
227
+ end
228
+
229
+ sat_max_load = avg_load_sat.max
230
+
231
+ # Populate the average Sunday load.
232
+ sun_load_sel = sun_load.values_at(*indices)
233
+ avg_load_sun = []
234
+ sun_load_sel = sun_load_sel.transpose
235
+ for i in 0..sun_load[0].length - 1
236
+ avg_load_sun[i] = (sun_load_sel[i].reduce(0, :+) / sun_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
237
+ end
238
+
239
+ sun_max_load = avg_load_sun.max
240
+
241
+ # Calculate the overall maximum load
242
+ max_load = [wkday_max_load, sat_max_load, sun_max_load].max
243
+
244
+ # Normalize each load profile based on the overall maximum load.
245
+
246
+ avg_load_wkday_norm = avg_load_wkday.map { |value| value / max_load }
247
+ avg_load_sat_norm = avg_load_sat.map { |value| value / max_load }
248
+ avg_load_sun_norm = avg_load_sun.map { |value| value / max_load }
249
+
250
+ end
251
+
252
+ # Create schedules for regular EV charging.
253
+ # Uses Sunday schedule for winter design day.
254
+ if chg_station_type != 'Pena Station Next Analysis--DC Fast Charger'
255
+ ev_sch_winter = OpenStudio::Model::ScheduleDay.new(model)
256
+ ev_sch.setWinterDesignDaySchedule(ev_sch_winter)
257
+ ev_sch.winterDesignDaySchedule.setName('EV Charging Winter Design Day')
258
+ # Loop through all the values and add to schedule
259
+ avg_load_sun_norm.each_with_index do |value, i| # Reading in the data from the array created from the csv file, with the values normalized to maximum power draw.
260
+ time = OpenStudio::Time.new(0, 0, (i + 1) * 15, 0) # OpenStudio::Time.new(day,hr of day, minute of hr, seconds of hr?)
261
+ ev_sch.winterDesignDaySchedule.addValue(time, value)
262
+ end
263
+ runner.registerInfo(" WDD schedule = #{avg_load_wkday_norm}")
264
+ # ...repeat for all 24 hrs (or whatever granularity)
265
+
266
+ # Summer design day. Uses weekday schedule for summer design day.
267
+ ev_sch_summer = OpenStudio::Model::ScheduleDay.new(model)
268
+ ev_sch.setSummerDesignDaySchedule(ev_sch_summer)
269
+ ev_sch.summerDesignDaySchedule.setName('EV Charging Summer Design Day')
270
+ # Loop through all the values and add to schedule
271
+ avg_load_wkday_norm.each_with_index do |value, i|
272
+ time = OpenStudio::Time.new(0, 0, (i + 1) * 15, 0) # OpenStudio::Time.new(day,hr of day, minute of hr, seconds of hr?)
273
+ ev_sch.summerDesignDaySchedule.addValue(time, value)
274
+ end
275
+
276
+ # Default day (use this for weekdays)
277
+ ev_sch.defaultDaySchedule.setName('EV Charging Default')
278
+ # Loop through all the values and add to schedule
279
+ avg_load_wkday_norm.each_with_index do |value, i|
280
+ time = OpenStudio::Time.new(0, 0, (i + 1) * 15, 0) # OpenStudio::Time.new(day,hr of day, minute of hr, seconds of hr?)
281
+ ev_sch.defaultDaySchedule.addValue(time, value)
282
+ end
283
+
284
+ # Saturday
285
+ ev_sch_sat_rule = OpenStudio::Model::ScheduleRule.new(ev_sch)
286
+ ev_sch_sat_rule.setName('ev_sch_sat_rule')
287
+ ev_sch_sat_rule.setApplySaturday(true)
288
+ ev_sch_sat = ev_sch_sat_rule.daySchedule
289
+ ev_sch_sat.setName('EV Charging Sat')
290
+ # Loop through all the values and add to schedule
291
+ avg_load_sat_norm.each_with_index do |value, i|
292
+ time = OpenStudio::Time.new(0, 0, (i + 1) * 15, 0) # OpenStudio::Time.new(day,hr of day, minute of hr, seconds of hr?)
293
+ ev_sch_sat.addValue(time, value)
294
+ end
295
+
296
+ # Sunday
297
+ ev_sch_sun_rule = OpenStudio::Model::ScheduleRule.new(ev_sch)
298
+ ev_sch_sun_rule.setName('ev_sch_sun_rule')
299
+ ev_sch_sun_rule.setApplySunday(true)
300
+ ev_sch_sun = ev_sch_sun_rule.daySchedule
301
+ ev_sch_sun.setName('EV Charging Sun')
302
+ # Loop through all the values and add to schedule
303
+ avg_load_sun_norm.each_with_index do |value, i|
304
+ time = OpenStudio::Time.new(0, 0, (i + 1) * 15, 0)
305
+ ev_sch_sun.addValue(time, value)
306
+ end
307
+ end
308
+
309
+ if chg_station_type != 'Pena Station Next Analysis--DC Fast Charger'
310
+
311
+ # Adding an EV charger definition and instance for the regular EV charging.
312
+ ev_charger_def = OpenStudio::Model::ExteriorFuelEquipmentDefinition.new(model)
313
+ ev_charger_level = max_load * 1000 # Converting from kW to watts
314
+ ev_charger_def.setName("#{ev_charger_level} w EV Charging Definition")
315
+ ev_charger_def.setDesignLevel(ev_charger_level)
316
+
317
+ # creating EV charger object for the regular EV charging.
318
+ ev_charger = OpenStudio::Model::ExteriorFuelEquipment.new(ev_charger_def, ev_sch)
319
+ ev_charger.setName("#{ev_charger_level} w EV Charger")
320
+ ev_charger.setFuelType('Electricity')
321
+ ev_charger.setEndUseSubcategory('Electric Vehicles')
322
+ runner.registerInfo("multiplier (kW) = #{max_load}}")
323
+ end
324
+ return true
325
+ end
326
+ end
327
+ # register the measure to be used by the application
328
+ AddEVLoad.new.registerWithApplication