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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -0
- data/Rakefile +3 -0
- data/lib/measures/ChangeBuildingLocation/measure.xml +11 -11
- data/lib/measures/ExportScheduleCSV/measure.rb +1 -1
- data/lib/measures/ExportScheduleCSV/measure.xml +16 -15
- data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.xml +7 -6
- data/lib/measures/MeterFlodPlot/measure.rb +1 -1
- data/lib/measures/MeterFlodPlot/measure.xml +16 -15
- data/lib/measures/ReportModelChanges/measure.xml +2 -2
- data/lib/measures/RunPeriodMultiple/measure.xml +12 -11
- data/lib/measures/ServerDirectoryCleanup/README.md +97 -3
- data/lib/measures/ServerDirectoryCleanup/measure.rb +1 -1
- data/lib/measures/ServerDirectoryCleanup/measure.xml +10 -59
- data/lib/measures/UnmetLoadHoursTroubleshooting/README.md +9 -3
- data/lib/measures/UnmetLoadHoursTroubleshooting/measure.rb +1 -1
- data/lib/measures/UnmetLoadHoursTroubleshooting/measure.xml +66 -17
- data/lib/measures/VentilationQAQC/README.md +9 -3
- data/lib/measures/VentilationQAQC/measure.rb +52 -45
- data/lib/measures/VentilationQAQC/measure.xml +25 -30
- data/lib/measures/ZoneReport/README.md +2 -2
- data/lib/measures/ZoneReport/measure.rb +1 -1
- data/lib/measures/ZoneReport/measure.xml +10 -11
- data/lib/measures/add_ems_to_control_ev_charging/LICENSE.MD.txt +15 -0
- data/lib/measures/{AddDaylightSensors → add_ems_to_control_ev_charging}/LICENSE.md +0 -0
- data/lib/measures/add_ems_to_control_ev_charging/ReadMe.MD +29 -0
- data/lib/measures/add_ems_to_control_ev_charging/measure.rb +288 -0
- data/lib/measures/add_ems_to_control_ev_charging/measure.xml +87 -0
- data/lib/measures/add_ev_load/LICENSE.MD.txt +15 -0
- data/lib/measures/{EnableDemandControlledVentilation → add_ev_load}/LICENSE.md +0 -0
- data/lib/measures/add_ev_load/ReadMe.MD +34 -0
- data/lib/measures/add_ev_load/measure.rb +328 -0
- data/lib/measures/add_ev_load/measure.xml +153 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/PSN_BuildingKey.csv +104 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/PSN_BuildingKey_v2.csv +104 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow1_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow2_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg1_dow3_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow1_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow2_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg2_dow3_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow1_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow2_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex1.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex2.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/chg3_dow3_flex3.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Saturday.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Sunday.csv +96 -0
- data/lib/measures/add_ev_load/resources/EV_Load_Profiles/fast_charge_15min_Weekday.csv +96 -0
- data/lib/measures/envelope_and_internal_load_breakdown/README.md +4 -3
- data/lib/measures/envelope_and_internal_load_breakdown/measure.rb +7 -4
- data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +16 -17
- data/lib/measures/envelope_and_internal_load_breakdown/resources/report.html.erb +1 -0
- data/lib/measures/example_report/README.md +27 -5
- data/lib/measures/example_report/measure.rb +7 -4
- data/lib/measures/example_report/measure.xml +16 -29
- data/lib/measures/example_report/resources/report.html.erb +1 -0
- data/lib/measures/gem_env_report/measure.xml +1 -1
- data/lib/measures/generic_qaqc/README.md +187 -5
- data/lib/measures/generic_qaqc/measure.rb +1 -1
- data/lib/measures/generic_qaqc/measure.xml +15 -85
- data/lib/measures/generic_qaqc/resources/report.html.erb +1 -0
- data/lib/measures/hvac_psychrometric_chart/README.md +11 -5
- data/lib/measures/hvac_psychrometric_chart/measure.rb +1 -1
- data/lib/measures/hvac_psychrometric_chart/measure.xml +13 -18
- data/lib/measures/hvac_psychrometric_chart/resources/report.html.erb +1 -0
- data/lib/measures/inject_idf_objects/measure.xml +25 -24
- data/lib/measures/openstudio_results/README.md +195 -5
- data/lib/measures/openstudio_results/measure.rb +2 -2
- data/lib/measures/openstudio_results/measure.xml +30 -154
- data/lib/measures/openstudio_results/resources/report.html.erb +1 -0
- data/lib/measures/set_run_period/measure.xml +2 -2
- data/lib/measures/{EnableEconomizerControl → view_data}/LICENSE.md +0 -0
- data/lib/measures/view_data/README.md +64 -0
- data/lib/measures/{AddDaylightSensors → view_data}/README.md.erb +0 -0
- data/lib/measures/view_data/measure.rb +454 -0
- data/lib/measures/view_data/measure.xml +159 -0
- data/lib/measures/view_data/resources/report.html.in +2881 -0
- data/lib/measures/view_data/resources/va3c.rb +1021 -0
- data/lib/measures/{ImproveFanBeltEfficiency → view_model}/LICENSE.md +0 -0
- data/lib/measures/view_model/README.md +26 -0
- data/lib/measures/{EnableDemandControlledVentilation → view_model}/README.md.erb +0 -0
- data/lib/measures/view_model/measure.rb +146 -0
- data/lib/measures/view_model/measure.xml +98 -0
- data/lib/measures/view_model/resources/report.html.in +2881 -0
- data/lib/measures/view_model/resources/va3c.rb +1021 -0
- data/lib/openstudio/common_measures/version.rb +1 -1
- data/openstudio-common-measures.gemspec +1 -1
- metadata +61 -71
- data/lib/measures/AddDaylightSensors/README.md +0 -136
- data/lib/measures/AddDaylightSensors/measure.rb +0 -521
- data/lib/measures/AddDaylightSensors/measure.xml +0 -233
- data/lib/measures/EnableDemandControlledVentilation/README.md +0 -32
- data/lib/measures/EnableDemandControlledVentilation/measure.rb +0 -154
- data/lib/measures/EnableDemandControlledVentilation/measure.xml +0 -99
- data/lib/measures/EnableEconomizerControl/README.md +0 -48
- data/lib/measures/EnableEconomizerControl/README.md.erb +0 -42
- data/lib/measures/EnableEconomizerControl/measure.rb +0 -172
- data/lib/measures/EnableEconomizerControl/measure.xml +0 -124
- data/lib/measures/ImproveFanBeltEfficiency/README.md +0 -104
- data/lib/measures/ImproveFanBeltEfficiency/README.md.erb +0 -42
- data/lib/measures/ImproveFanBeltEfficiency/measure.rb +0 -366
- data/lib/measures/ImproveFanBeltEfficiency/measure.xml +0 -185
- data/lib/measures/ImproveMotorEfficiency/LICENSE.md +0 -27
- data/lib/measures/ImproveMotorEfficiency/README.md +0 -104
- data/lib/measures/ImproveMotorEfficiency/README.md.erb +0 -42
- data/lib/measures/ImproveMotorEfficiency/measure.rb +0 -365
- data/lib/measures/ImproveMotorEfficiency/measure.xml +0 -182
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/LICENSE.md +0 -27
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/README.md +0 -64
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/README.md.erb +0 -42
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.rb +0 -422
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.xml +0 -150
- data/lib/measures/IncreaseInsulationRValueForRoofs/LICENSE.md +0 -27
- data/lib/measures/IncreaseInsulationRValueForRoofs/README.md +0 -64
- data/lib/measures/IncreaseInsulationRValueForRoofs/README.md.erb +0 -42
- data/lib/measures/IncreaseInsulationRValueForRoofs/measure.rb +0 -422
- data/lib/measures/IncreaseInsulationRValueForRoofs/measure.xml +0 -143
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/LICENSE.md +0 -27
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/README.md +0 -97
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/README.md.erb +0 -42
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.rb +0 -450
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.xml +0 -186
- data/lib/measures/ReduceLightingLoadsByPercentage/LICENSE.md +0 -27
- data/lib/measures/ReduceLightingLoadsByPercentage/README.md +0 -96
- data/lib/measures/ReduceLightingLoadsByPercentage/README.md.erb +0 -42
- data/lib/measures/ReduceLightingLoadsByPercentage/measure.rb +0 -513
- data/lib/measures/ReduceLightingLoadsByPercentage/measure.xml +0 -191
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/LICENSE.md +0 -27
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/README.md +0 -104
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/README.md.erb +0 -42
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.rb +0 -349
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.xml +0 -181
- data/lib/measures/ReduceVentilationByPercentage/LICENSE.md +0 -27
- data/lib/measures/ReduceVentilationByPercentage/README.md +0 -40
- data/lib/measures/ReduceVentilationByPercentage/README.md.erb +0 -42
- data/lib/measures/ReduceVentilationByPercentage/measure.rb +0 -291
- data/lib/measures/ReduceVentilationByPercentage/measure.xml +0 -96
- data/lib/measures/VentilationQAQC/ExampleModel.osm +0 -28468
- data/lib/measures/create_variable_speed_rtu/LICENSE.md +0 -27
- data/lib/measures/create_variable_speed_rtu/README.md +0 -120
- data/lib/measures/create_variable_speed_rtu/README.md.erb +0 -42
- data/lib/measures/create_variable_speed_rtu/measure.rb +0 -539
- data/lib/measures/create_variable_speed_rtu/measure.xml +0 -207
- data/lib/measures/radiant_slab_with_doas/LICENSE.md +0 -27
- data/lib/measures/radiant_slab_with_doas/README.md +0 -156
- data/lib/measures/radiant_slab_with_doas/README.md.erb +0 -42
- data/lib/measures/radiant_slab_with_doas/measure.rb +0 -403
- 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.
|
File without changes
|
@@ -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
|