-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Model EV Batteries #1533
base: master
Are you sure you want to change the base?
Model EV Batteries #1533
Conversation
…o ev_batteries # Conflicts: # BuildResidentialHPXML/measure.rb # HPXMLtoOpenStudio/resources/battery.rb # HPXMLtoOpenStudio/resources/hpxml_defaults.rb
… into ev_batteries
Yes, for now we plan to limit to 1 EV/unit. However, the current implementation does allow for one home battery and one EV battery and expects separate schedules for each. |
I assume that probably won't work, for the same reason that modeling two home batteries wasn't previously supported. But we can worry about that later. More of a heads up for now. |
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_miles_per_year', false) | ||
arg.setDisplayName('Electric Vehicle: Miles Traveled') | ||
arg.setDescription('The annual miles traveled by the EV.') | ||
arg.setUnits('miles') | ||
args << arg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used to calculate the effective discharge power in vehicles.rb (power = kwh/mile * annl_miles / driving hours)
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_hours_per_week', false) | ||
arg.setDisplayName('Electric Vehicle: Hours Driven per Week') | ||
arg.setDescription('The weekly hours traveled by the EV.') | ||
arg.setUnits('hours') | ||
args << arg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not currently used, but will be needed in schedule generation PR
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_fraction_charged_home', false) | ||
arg.setDisplayName('Electric Vehicle: Fraction Charged at Home') | ||
arg.setDescription('The fraction charging energy provided by the at-home charger.') | ||
args << arg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this argument belongs here. It will be used in ResStockArguments to scale the miles/year, which influences the schedule. I liked that it persists into the HPXML to give context to the miles/year, but the fraction is not used directly in OS-HPXML.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow. Why wouldn't OS-HPXML use this?This should affect how much charging is done at home, no?
charging_schedule = schedules_file.create_schedule_file(model, col_name: SchedulesFile::Columns[:BatteryCharging].name) | ||
discharging_schedule = schedules_file.create_schedule_file(model, col_name: SchedulesFile::Columns[:BatteryDischarging].name) | ||
elsif is_ev | ||
charging_schedule, discharging_schedule = Vehicle.get_ev_charging_schedules(runner, model, battery, schedules_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get schedule file or schedule ruleset for EV
# Calculate effective discharge power and rated power output | ||
# Scale the effective discharge power by 2.25 to assign the rated discharge power. This value reflects the maximum power adjustment allowed in the EMS EV discharge program at -17.8 C. | ||
ev_annl_energy = vehicle.energy_efficiency * vehicle.miles_per_year # kWh/year | ||
eff_discharge_power = UnitConversions.convert(ev_annl_energy / annual_driving_hours, 'kw', 'w') # W | ||
vehicle.rated_power_output = eff_discharge_power * 2.25 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rated power output is set to avoid ever limiting the actual discharge power at a timestep. This means that some combinations of inputs could result in very high and unrealistic effective discharge powers (eg, high miles, low hours == high annual energy over a short amount of hours). Granted, this would only happen under unrealistic combinations of inputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts on including this file which shows the calculation of the default vehicle charging/discharging schedules?
…o ev_batteries # Conflicts: # HPXMLtoOpenStudio/measure.xml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of good stuff here. Here's my initial batch of comments, mostly focused on the BuildResHPXML measure, hpxml.rb class, schematron, and documentation. My main comments are:
- Generalize the HPXML Vehicle implementation; we are only modeling EVs today, but everything should be generalized in case we include other vehicle types in the future.
- Use better consistency between HPXML schema and arguments/properties/variables/descriptions.
arg = OpenStudio::Measure::OSArgument::makeBoolArgument('ev_battery_present', false) | ||
arg.setDisplayName('Electric Vehicle: Present') | ||
arg.setDescription('Whether there is an electric vehicle battery present. If the `misc_plug_loads_vehicle_present` argument is true, this argument is superseded and vehicle charging will be modeled as a plug load only.') | ||
arg.setDefaultValue(false) | ||
args << arg | ||
|
||
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_battery_capacity', false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you generalize this to better match the generic Vehicle
element in HPXML? I.e.:
- Replace "Electric Vehicle: Present" with "Vehicle: Type" where you can choose EV, ICE, etc., or "none". Default to "none".
- Change all the display names from "Electric Vehicle: Foo" to be "Vehicle: Foo" and, for those arguments that only apply for certain vehicle types, say so in the description. (You'll find lots of examples of this in the code.) You may have to update the
set_electric_vehicle()
method a bit too use the vehicle type argument. - Change all descriptions to refer to "vehicle" instead of "EV".
- Change all the arguments from
ev_battery_foo
tovehicle_foo
.
This would allow someone to create an HPXML with other vehicle types too. Hopefully not too much work...
|
||
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_battery_capacity', false) | ||
arg.setDisplayName('Electric Vehicle: Nominal Battery Capacity') | ||
arg.setDescription('The nominal capacity of the EV battery. If not provided, the OS-HPXML default is used.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anytime you say "the OS-HPXML default is used", please include a link to the documentation. You'll find lots of examples where we do this.
arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('battery_num_bedrooms_served', false) | ||
arg.setDisplayName('Battery: Number of Bedrooms Served') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this home battery argument got split from the rest. Please move it up.
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_energy_efficiency', false) | ||
arg.setDisplayName('Electric Vehicle: Energy Efficiency') | ||
arg.setDescription('The efficiency of the EV. If not provided, the OS-HPXML default is used.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no "Energy Efficiency" element in the HPXML. Please use the same names that are used in the schema, otherwise it is confusing. Seems like it is "Combined Fuel Economy"?
Also, we should probably split this argument in two: the units (choice enumeration, it's fine if only "kWh/mile" is supported today) and the value. You can find examples of this in other arguments in the measure.
arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ev_miles_per_year', false) | ||
arg.setDisplayName('Electric Vehicle: Miles Traveled') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Match HPXML schema... I assume "Miles Driven Per Year"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename to vehicle-ev-foo.csv
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename to vehicle-ev.csv
?
@@ -93,7 +93,7 @@ Annual energy outputs are listed below. | |||
==================================== =========================== | |||
Type Notes | |||
==================================== =========================== | |||
Energy Use: Total (MBtu) Total energy consumption; includes any battery charging/discharging | |||
Energy Use: Total (MBtu) Total energy consumption; includes any home battery charging/discharging, excludes electric vehicle discharging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of confused by this since it doesn't say anything about EV charging. Is this a simpler version of what you're trying to say?
Energy Use: Total (MBtu) Total energy consumption; includes any home battery charging/discharging, excludes electric vehicle discharging | |
Energy Use: Total (MBtu) Total energy consumption; includes any home battery charging/discharging and EV charging |
Make similar edits below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add Unmet Hours: Driving (hr)
output and description.
def self.apply_electric_vehicle(runner, model, spaces, hpxml_bldg, vehicle, schedules_file) | ||
model.getElectricEquipments.sort.each do |ee| | ||
if ee.endUseSubcategory.start_with? Constants::ObjectTypeMiscElectricVehicleCharging | ||
runner.registerWarning('Electric vehicle was specified as a plug load and as a battery, vehicle charging will be modeled as a plug load.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see you have a warning for this. 👍
runner.registerWarning('Electric vehicle was specified as a plug load and as a battery, vehicle charging will be modeled as a plug load.') | |
runner.registerWarning('Electric vehicle charging was specified as both a PlugLoad and a Vehicle, the latter will be ignored.') |
(If you accept the suggestion, there are other files that need to be updated too.)
…assigned garage doors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you also changed the order of where the EV charging output occurs. That's probably fine, but please update the order in the documentation too.
# Assign charging and vehicle space | ||
ev_charger = vehicle.ev_charger | ||
if ev_charger.nil? | ||
runner.registerWarning('Electric vehicle specified with no charger provided; battery will not be modeled.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runner.registerWarning('Electric vehicle specified with no charger provided; battery will not be modeled.') | |
runner.registerWarning('Electric vehicle specified with no charger provided; EV charging will not be modeled.') |
# Get schedules to calculate effective discharge power | ||
charging_schedule, discharging_schedule = get_ev_charging_schedules(runner, model, vehicle, schedules_file) | ||
if charging_schedule.nil? && discharging_schedule.nil? | ||
runner.registerWarning('Electric vehicle battery specified with no charging/discharging schedule provided; battery will not be modeled.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused. Are schedules required? The schematron/docs say they are optional and that there are defaults.
hpxml_bldg.vehicles.each do |vehicle| | ||
next unless vehicle.vehicle_type == HPXML::VehicleTypeBEV |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add a warning for non-BEV vehicles to make it clear we are not modeling them. Something like this. And add a test in test_validation.rb.
Pull Request Description
Allows detailed modeling of EVs using the EnergyPlus battery model, whereas previous EV charging was limited to a simple plug load. This PR adds arguments to define EV battery parameters, EV charger parameters, driving behavior such as miles traveled, and detailed charging and discharging schedules. The E+ battery model was used so that bidirectional charging can be supported in the future, but this capability is not included in this PR.
Key aspects of this PR include:
Electricity: Electric Vehicle Charging (MBtu)
and writes a new "Unmet Hours" output typeDriving (hr)
(if specified)Companion HPXML PR: hpxmlwg/hpxml#403
Schedule generation PR: #1757
Checklist
PR Author: Check these when they're done. Not all may apply.
strikethroughand check any that do not apply.PR Reviewer: Verify each has been completed.
EPvalidator.xml
) has been updatedtasks.rb
)HPXMLtoOpenStudio/tests
and/orworkflow/tests/hpxml_translator_test.rb
)openstudio tasks.rb update_measures
has been run