Repository: NREL/OpenStudio (language: python)

Issue:
Add Fuel-related Methods from OpenStudio-Standards
Enhancement Request
--------------
Implement guel-related methods from OpenStudio-Standards that have proven useful but which have not yet been implemented in C++.

## Detailed Description


Originally described in https://github.com/NREL/OpenStudio/issues/4792, this is enhancement request is just the fuel-related methods, so the work is broken in two distinct PRs.

## Possible Implementation

[Siz.ThermalZone.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb)
```
OpenStudio::Model::ThermalZone
  
  heating_fuels()
  
  cooling_fuels()
```

[Siz.HeatingCoolingFuels.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb) 
```
OpenStudio::Model::Model

  plant_loop_heating_fuels()
  
  plant_loop_cooling_fuels()
  
  coil_heating_fuels()
  
  coil_heat_type()
  
  airloop_primary_heat_type()
  
  zone_equipment_heat_type()
  
  coil_cooling_fuels()
  
  zone_equipment_heating_fuels()
  
  zone_equipment_cooling_fuels()
  
  zone_airloop_heating_fuels()
  
  zone_airloop_cooling_fuels()
```

Also add all the Ruby methods defined in these files that aren't already in OpenStudio C++, which will enable a lot of code and files to be removed from openstudio-results measure, as pointed out by @eringold.

https://github.com/NREL/openstudio-common-measures-gem/tree/develop/lib/measures/openstudio_results/resources

Add Fuel-related Methods from OpenStudio-Standards
Enhancement Request
--------------
Implement guel-related methods from OpenStudio-Standards that have proven useful but which have not yet been implemented in C++.

## Detailed Description


Originally described in https://github.com/NREL/OpenStudio/issues/4792, this is enhancement request is just the fuel-related methods, so the work is broken in two distinct PRs.

## Possible Implementation

[Siz.ThermalZone.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb)
```
OpenStudio::Model::ThermalZone
  
  heating_fuels()
  
  cooling_fuels()
```

[Siz.HeatingCoolingFuels.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb) 
```
OpenStudio::Model::Model

  plant_loop_heating_fuels()
  
  plant_loop_cooling_fuels()
  
  coil_heating_fuels()
  
  coil_heat_type()
  
  airloop_primary_heat_type()
  
  zone_equipment_heat_type()
  
  coil_cooling_fuels()
  
  zone_equipment_heating_fuels()
  
  zone_equipment_cooling_fuels()
  
  zone_airloop_heating_fuels()
  
  zone_airloop_cooling_fuels()
```

Also add all the Ruby methods defined in these files that aren't already in OpenStudio C++, which will enable a lot of code and files to be removed from openstudio-results measure, as pointed out by @eringold.

https://github.com/NREL/openstudio-common-measures-gem/tree/develop/lib/measures/openstudio_results/resources

Add Autosizing/Hardsizing Methods from OpenStudio-Standards
Enhancement Request
--------------
Implement autosize/hardsize-related methods from OpenStudio-Standards that have proven useful but which have not yet been implemented in C++.

## Detailed Description
The autosizing methods below fall into several categories. 
1. They are calculated using a combination of other autosizable fields, for example `Coil:Cooling:Water.autosizedDesignCoilLoad()`
2. They pull sizing values from an associated object, for example, some values of a `ThermalZone` actually come from the `Sizing:Zone` object associated with it.
3. They are utility methods that have proven useful and should be in C++.

The Ruby implementations of these methods is available in the openstudio-standards files linked below. Some of the fuel-related methods should probably be implemented on the ModelObject classes instead of on Model.

## Possible Implementation

[Siz.AirLoopHVAC.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb)
```
OpenStudio::Model::AirLoopHVAC

  autosizedSumMinimumHeatingAirFlowRates()

  autosizedSumAirTerminalMaxAirFlowRate()
```

[Siz.CoilCoolingWater.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb)
```
OpenStudio::Model::CoilCoolingWater
  
  autosizedDesignCoilLoad()
```

[Siz.ThermalZone.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb)
```
OpenStudio::Model::ThermalZone

  autosizedMaximumOutdoorAirFlowRate()

  autosizedMinimumOutdoorAirFlowRate()

  autosizedCoolingDesignAirFlowRate()
  
  autosizedHeatingDesignAirFlowRate()
  
  coolingDesignLoad()
  
  designAirFlowRate()
  
  heatingDesignLoad()
  
  heating_fuels()
  
  cooling_fuels()
```

[Siz.HeatingCoolingFuels.rb](https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb) 
```
OpenStudio::Model::Model

  plant_loop_heating_fuels()
  
  plant_loop_cooling_fuels()
  
  coil_heating_fuels()
  
  coil_heat_type()
  
  airloop_primary_heat_type()
  
  zone_equipment_heat_type()
  
  coil_cooling_fuels()
  
  zone_equipment_heating_fuels()
  
  zone_equipment_cooling_fuels()
  
  zone_airloop_heating_fuels()
  
  zone_airloop_cooling_fuels()
```

Also add all the Ruby methods defined in these files that aren't already in OpenStudio C++, which will enable a lot of code and files to be removed from openstudio-results measure, as pointed out by @eringold.

https://github.com/NREL/openstudio-common-measures-gem/tree/develop/lib/measures/openstudio_results/resources



Discussion / hints:


@tijcolem here are the methods that are left over after comparing the Ruby to the C++. Happy to discuss implementation details if you want.
+100, so these files can be removed from openstudio_results: https://github.com/NREL/openstudio-common-measures-gem/tree/develop/lib/measures/openstudio_results/resources
@eringold Good call, I had only been looking at openstudio-standards, but these methods in the results measure should also be moved to C++.
I always found it quite weird that we go fetch into the `TabularDataWithStrings` and not the dedicated `ComponentSizes` table.

openstudio-standards does:

```sql
SELECT Value FROM tabulardatawithstrings
  WHERE ReportName='ComponentSizingSummary'
    AND ReportForString='Entire Facility'
    AND TableName='AirLoopHVAC'
    AND ColumnName='Sum of Air Terminal Minimum Heating Flow Rates'
    AND RowName='VAV WITH REHEAT'
    AND Units='m3/s'
```

When we could do

```sql
SELECT Value FROM ComponentSizes
  WHERE CompType = "AirLoopHVAC"
    AND Description = "Sum of Air Terminal Minimum Heating Flow Rates"
    AND Units='m3/s'
    AND CompName='VAV WITH REHEAT' 
```

But that's kinda fine. The issue is more that what the OS SDK does is a lot worse though...

It goes into the InitializationSummary report, table "Component Sizing Information", which is an absolute mess in the SQL file.
It does a first sql call to get the RowNames that match the name of the component. Then it **loops** on every row until it finds the specific one it's looking for, then does a final call for the Value itself. 

What the two versions above accomplish in a single sql call could potentially take 11 sql calls in this specific example (since there are 9 rowNames returned)...

I seem to recall that in the past E+ **did** have more information in the Initialization Summary than in ComponentSizes, but I would hope that it's been resolved since (or can be)

https://github.com/NREL/OpenStudio/blob/3561eb529cc1ed778222958badd4320749efe7ef/src/model/ModelObject.cpp#L228-L377
@jmarrec yeah I agree. Some of the choices in the C++ were based on what was available in E+ at the time, which has probably changed/improved since that was done. Anything low effort that speeds up the queries sounds good to me.
I've tested it, only a handful of objects aren't in componentssizes. I'll make it default to the efficient query, only those will do the inefficient one. And I'll implement the missing ones. Should I have a question on implementation details, do I reach you here or on slack? (I don't foresee a lot of questions)
I hadn't realized at first that a bunch of the methods are about fuelTypes and that has nothing to do with SQL. I may break this issue in 2
I don't think these two actually work: `ThermalZone::autosizedMaximumOutdoorAirFlowRate` / `autosizedMinimumOutdoorAirFlowRate` : https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb#L5-L17
@asparke2 there's a typo here in the time being FYI: https://github.com/NREL/openstudio-standards/blob/ba5168e63a87ac25d6092a61658f0741a0f8e2e8/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb#L618

missing a 'p'

Fix patch:
diff --git a/developer/python/Check_FuelType_Methods.ipynb b/developer/python/Check_FuelType_Methods.ipynb
new file mode 100644
index 00000000000..7e503b964f7
--- /dev/null
+++ b/developer/python/Check_FuelType_Methods.ipynb
@@ -0,0 +1,945 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "dd228051",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pathlib import Path\n",
+    "import glob as gb\n",
+    "import re\n",
+    "import os"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "b396635d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ROOT_DIR = Path('.').absolute().parent.parent\n",
+    "MODEL_DIR = ROOT_DIR / 'src' / 'model'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "493bfb43",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cpp_files = sorted(list(MODEL_DIR.glob('*.cpp')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "a97065e3",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class ComponentTypeInfo:\n",
+    "    def __init__(self, is_simple: bool, simple_return: str = None, func_body: str = None):\n",
+    "        self.is_simple = is_simple\n",
+    "        self.simple_return = simple_return\n",
+    "        self.func_body = func_body\n",
+    "    def __repr__(self):\n",
+    "        if self.is_simple:\n",
+    "            return self.simple_return\n",
+    "        else:\n",
+    "            return \"Complex\"\n",
+    "    def __str__(self):\n",
+    "        if self.is_simple:\n",
+    "            return self.simple_return\n",
+    "        else:\n",
+    "            return f\"Complex: {func_body}\"\n",
+    "\n",
+    "class ClassInfo:\n",
+    "    def __init__(self, class_name: str):\n",
+    "        self.class_name = class_name\n",
+    "        self.component_type = None\n",
+    "        self.cooling_fuel_types = None\n",
+    "        self.heating_fuel_types = None\n",
+    "        self.appg_heating_fuel_types = None\n",
+    "        \n",
+    "    @staticmethod\n",
+    "    def header():\n",
+    "        return [\"Class_Name\", \"ComponentType\", \"coolingFuelTypes\", \"heatingFuelTypes\", \"appGHeatingFuelTypes\"]\n",
+    "    \n",
+    "    def __repr__(self):\n",
+    "        return f\"{self.class_name},{self.component_type.__repr__()},{self.cooling_fuel_types.__repr__()},{self.heating_fuel_types.__repr__()},{self.appg_heating_fuel_types.__repr__()}\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "cb16f193",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "RE_SIMPLE_COMPTYPE = re.compile(r'return ComponentType::(Cooling|Heating|None);')\n",
+    "RE_SIMPLE_FUELTYPE = re.compile(r'return (.*);')\n",
+    "\n",
+    "RE_INSERT_FUELTYPE = re.compile(r'result.insert\\(FuelType::(.*?)\\);')\n",
+    "RE_INSERT_CONVERTFUELTYPE = re.compile(r'result.insert\\(FuelType\\(.*?\\)\\);')\n",
+    "\n",
+    "RE_INSERT_FUELTYPE_APPG = re.compile(r'result.insert\\(AppGFuelType::(.*?)\\);')\n",
+    "RE_INSERT_CONVERTFUELTYPE_APPG = re.compile(r'result.insert\\(convertFuelTypeToAppG\\(.*?\\)\\);')\n",
+    "\n",
+    "\n",
+    "\n",
+    "RE_GET_AIRLOOP_HEATING = re.compile(r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*return a_->heatingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "RE_GET_AIRLOOP_COOLING = re.compile(r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*return a_->coolingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "RE_GET_AIRLOOP_APPG = re.compile(r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*return a_->appGHeatingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "\n",
+    "\n",
+    "RE_GET_PLANTLOOP_HEATING = re.compile(r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*return p_->heatingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "RE_GET_PLANTLOOP_COOLING = re.compile(r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*return p_->coolingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "RE_GET_PLANTLOOP_APPG = re.compile(r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*return p_->appGHeatingFuelTypes\\(\\);\\s*}\\s*return {};\\s*',\n",
+    "                                    re.DOTALL)\n",
+    "\n",
+    "RE_INSERT_AIRLOOP_HEATING = re.compile(\n",
+    "    r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*for \\(auto ft : a_->heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_AIRLOOP_COOLING = re.compile(\n",
+    "    r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*for \\(auto ft : a_->coolingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_AIRLOOP_APPG = re.compile(\n",
+    "    r'\\s*if \\(auto a_ = airLoopHVAC\\(\\)\\) {\\s*for \\(auto ft : a_->appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "\n",
+    "RE_INSERT_PLANTLOOP_HEATING = re.compile(\n",
+    "    r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*for \\(auto ft : p_->heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_PLANTLOOP_COOLING = re.compile(\n",
+    "    r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*for \\(auto ft : p_->coolingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_PLANTLOOP_APPG = re.compile(\n",
+    "    r'\\s*if \\(auto p_ = plantLoop\\(\\)\\) {\\s*for \\(auto ft : p_->appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_REHEAT_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : reheatCoil\\(\\).heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_REHEAT_COIL_APPG = re.compile(\n",
+    "    r'\\s*for \\(auto ft : reheatCoil\\(\\).appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "\n",
+    "\n",
+    "RE_INSERT_HEAT_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : heatingCoil\\(\\).heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_OPT_HEAT_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : hc_->heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_HEAT_COIL_APPG = re.compile(\n",
+    "    r'\\s*for \\(auto ft : heatingCoil\\(\\).appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_OPT_HEAT_COIL_APPG = re.compile(\n",
+    "    r'\\s*for \\(auto ft : hc_->appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "\n",
+    "RE_INSERT_SUPHC_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : supplementalHeatingCoil\\(\\).heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_OPT_SUPHC_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : supHC_->heatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_SUPHC_COIL_APPG = re.compile(\n",
+    "    r'\\s*for \\(auto ft : supplementalHeatingCoil\\(\\).appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "RE_INSERT_OPT_SUPHC_COIL_APPG = re.compile(\n",
+    "    r'\\s*for \\(auto ft : supHC_->appGHeatingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "\n",
+    "\n",
+    "RE_INSERT_COOL_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : coolingCoil\\(\\).coolingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")\n",
+    "\n",
+    "\n",
+    "RE_INSERT_OPT_COOL_COIL = re.compile(\n",
+    "    r'\\s*for \\(auto ft : cc_->coolingFuelTypes\\(\\)\\) {\\s*result.insert\\(ft\\);\\s*}',\n",
+    "    re.DOTALL\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "7443cca1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def get_func_body(lines, i):\n",
+    "    c = lines[i].count('{') - lines[i].count('}')\n",
+    "    k = i\n",
+    "    while c != 0:\n",
+    "        k += 1\n",
+    "        c += lines[k].count('{') - lines[k].count('}')\n",
+    "    func_body = \"\\n\".join(lines[i:k+1])\n",
+    "    func_body = func_body[func_body.find('{')+1:func_body.rfind('}')].strip()\n",
+    "    return k, func_body"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "f32698fe",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def parse_coolingFuelTypeFuncBod(func_body: str):\n",
+    "    if m := RE_SIMPLE_FUELTYPE.match(func_body):\n",
+    "        fuel_type = m.groups()[0].strip()\n",
+    "        if fuel_type == '{}':\n",
+    "            fuel_type = ''\n",
+    "        elif fuel_type.startswith('{') and fuel_type.endswith('}'):\n",
+    "            fuel_type = fuel_type.replace('FuelType::', '')\n",
+    "            if ',' in fuel_type:\n",
+    "                fuel_type = f'\"{fuel_type}\"'\n",
+    "            else:\n",
+    "                fuel_type = fuel_type[1:-1]\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=fuel_type, func_body=func_body)\n",
+    "            \n",
+    "    if RE_GET_AIRLOOP_COOLING.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='airLoopHVAC_->coolingFuelTypes()', func_body=func_body)\n",
+    "    \n",
+    "    if RE_GET_PLANTLOOP_COOLING.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='plantLoop_->coolingFuelTypes()', func_body=func_body)\n",
+    "    \n",
+    "    s = []\n",
+    "    if m := RE_INSERT_FUELTYPE.search(func_body):\n",
+    "        s.append(m.groups()[0])\n",
+    "    if RE_INSERT_CONVERTFUELTYPE.search(func_body):\n",
+    "        s.append('fuelType()')\n",
+    "    if RE_INSERT_AIRLOOP_COOLING.search(func_body):\n",
+    "        s.append('airLoopHVAC_->coolingFuelTypes()')\n",
+    "    if RE_INSERT_PLANTLOOP_COOLING.search(func_body):\n",
+    "        s.append('plantLoop_->coolingFuelTypes()')\n",
+    "    if RE_INSERT_COOL_COIL.search(func_body):\n",
+    "        s.append('cc.coolingFuelTypes()')\n",
+    "    if RE_INSERT_OPT_COOL_COIL.search(func_body):\n",
+    "        s.append('cc_->coolingFuelTypes()')\n",
+    "        \n",
+    "\n",
+    "    if s:\n",
+    "        # print(s)\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=\" + \".join(s), func_body=func_body)\n",
+    "    \n",
+    "    return ComponentTypeInfo(is_simple=False, func_body=func_body)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "734196a5",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"{Electricity, OtherFuel_1}\""
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "func_body = \"\"\"\n",
+    "{\n",
+    "      std::set<FuelType> result;\n",
+    "      result.insert(FuelType::Electricity);\n",
+    "      if (auto p_ = plantLoop()) {\n",
+    "        for (auto ft : p_->coolingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "      return {};\n",
+    "    }\n",
+    "\"\"\"\n",
+    "func_body = 'return {FuelType::Electricity, FuelType::OtherFuel_1};  // TODO: is that right?'\n",
+    "parse_coolingFuelTypeFuncBod(func_body)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "cdce9e6c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def parse_heatingFuelTypeFuncBod(func_body: str):\n",
+    "    if m := RE_SIMPLE_FUELTYPE.match(func_body):\n",
+    "        fuel_type = m.groups()[0].strip()\n",
+    "        if fuel_type == '{}':\n",
+    "            fuel_type = ''\n",
+    "        elif fuel_type.startswith('{') and fuel_type.endswith('}'):\n",
+    "            fuel_type = fuel_type.replace('FuelType::', '')\n",
+    "            if ',' in fuel_type:\n",
+    "                fuel_type = f'\"{fuel_type}\"'\n",
+    "            else:\n",
+    "                fuel_type = fuel_type[1:-1]\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=fuel_type)\n",
+    "    \n",
+    "    if RE_GET_AIRLOOP_HEATING.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='airLoopHVAC_->heatingFuelTypes()')\n",
+    "    \n",
+    "    if RE_GET_PLANTLOOP_HEATING.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='plantLoop_->heatingFuelTypes()')\n",
+    "    \n",
+    "    s = []\n",
+    "    if m := RE_INSERT_FUELTYPE.search(func_body):\n",
+    "        s.append(m.groups()[0])\n",
+    "    if RE_INSERT_CONVERTFUELTYPE.search(func_body):\n",
+    "        s.append('fuelType()')\n",
+    "        \n",
+    "    if RE_INSERT_AIRLOOP_HEATING.search(func_body):\n",
+    "        s.append('airLoopHVAC_->heatingFuelTypes()')\n",
+    "    if RE_INSERT_PLANTLOOP_HEATING.search(func_body):\n",
+    "        s.append('airLoopHVAC_->heatingFuelTypes()')\n",
+    "    if RE_INSERT_HEAT_COIL.search(func_body):\n",
+    "        s.append('hc.heatingFuelTypes()')\n",
+    "    if RE_INSERT_OPT_HEAT_COIL.search(func_body):\n",
+    "        s.append('hc_->heatingFuelTypes()')\n",
+    "    if RE_INSERT_REHEAT_COIL.search(func_body):\n",
+    "        s.append('reheatCoil.heatingFuelTypes()')\n",
+    "    if RE_INSERT_SUPHC_COIL.search(func_body):\n",
+    "        s.append('supHC.heatingFuelTypes()')\n",
+    "    if RE_INSERT_OPT_SUPHC_COIL.search(func_body):\n",
+    "        s.append('supHC_->heatingFuelTypes()')\n",
+    "    if s:\n",
+    "        # print(s)\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=\" + \".join(s))\n",
+    "    \n",
+    "    return ComponentTypeInfo(is_simple=False, func_body=func_body)\n",
+    "\n",
+    "def parse_appGHeatingFuelTypeFuncBod(func_body: str):\n",
+    "    if m := RE_SIMPLE_FUELTYPE.match(func_body):\n",
+    "        fuel_type = m.groups()[0].strip()\n",
+    "        if fuel_type == '{}':\n",
+    "            fuel_type = ''\n",
+    "        elif fuel_type.startswith('{') and fuel_type.endswith('}'):\n",
+    "            fuel_type = fuel_type.replace('AppGFuelType::', '')\n",
+    "            if ',' in fuel_type:\n",
+    "                fuel_type = f'\"{fuel_type}\"'\n",
+    "            else:\n",
+    "                fuel_type = fuel_type[1:-1]\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=fuel_type, func_body=func_body)\n",
+    "            \n",
+    "    if RE_GET_AIRLOOP_APPG.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='airLoopHVAC_->appGHeatingFuelTypes()', func_body=func_body)\n",
+    "    \n",
+    "    if RE_GET_PLANTLOOP_APPG.match(func_body):\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return='plantLoop_->appGHeatingFuelTypes()', func_body=func_body)\n",
+    "    \n",
+    "    s = []\n",
+    "    \n",
+    "    if m := RE_INSERT_FUELTYPE_APPG.search(func_body):\n",
+    "        s.append(m.groups()[0])\n",
+    "    if RE_INSERT_CONVERTFUELTYPE_APPG.search(func_body):\n",
+    "        s.append('fuelType()')\n",
+    "        \n",
+    "    if RE_INSERT_AIRLOOP_APPG.search(func_body):\n",
+    "        s.append('airLoopHVAC_->appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_PLANTLOOP_APPG.search(func_body):\n",
+    "        s.append('airLoopHVAC_->appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_HEAT_COIL_APPG.search(func_body):\n",
+    "        s.append('hc.appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_OPT_HEAT_COIL_APPG.search(func_body):\n",
+    "        s.append('hc_->appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_REHEAT_COIL_APPG.search(func_body):\n",
+    "        s.append('reheatCoil.appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_SUPHC_COIL_APPG.search(func_body):\n",
+    "        s.append('supHC.appGHeatingFuelTypes()')\n",
+    "    if RE_INSERT_OPT_SUPHC_COIL_APPG.search(func_body):\n",
+    "        s.append('supHC_->appGHeatingFuelTypes()')\n",
+    "    if s:\n",
+    "        # print(s)\n",
+    "        return ComponentTypeInfo(is_simple=True, simple_return=\" + \".join(s), func_body=func_body)\n",
+    "    \n",
+    "    return ComponentTypeInfo(is_simple=False, func_body=func_body)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "d5719d30",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "hc_->heatingFuelTypes() + supHC_->heatingFuelTypes()"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "func_body = \"\"\"\n",
+    "{\n",
+    "      std::set<FuelType> result;\n",
+    "      if (auto hc_ = heatingCoil()) {\n",
+    "        for (auto ft : hc_->heatingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "      // TODO: is supplemental needed?\n",
+    "      if (auto supHC_ = supplementalHeatingCoil()) {\n",
+    "        for (auto ft : supHC_->heatingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "\n",
+    "      return {result.begin(), result.end()};\n",
+    "    }\n",
+    "\"\"\"\n",
+    "parse_heatingFuelTypeFuncBod(func_body)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "22cdb75b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "airLoopHVAC_->appGHeatingFuelTypes() + reheatCoil.appGHeatingFuelTypes()"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "func_body = \"\"\"{\n",
+    "      std::set<AppGFuelType> result;\n",
+    "      if (auto hc_ = heatingCoil()) {\n",
+    "        for (auto ft : hc_->appGHeatingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "      // TODO: is supplemental needed?\n",
+    "      if (auto supHC_ = supplementalHeatingCoil()) {\n",
+    "        for (auto ft : supHC_->appGHeatingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "      return {result.begin(), result.end()};\n",
+    "    }\"\"\"\n",
+    "\n",
+    "func_body = \"\"\"{\n",
+    "      std::set<AppGFuelType> result;\n",
+    "      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {\n",
+    "        result.insert(ft);\n",
+    "      }\n",
+    "      if (auto a_ = airLoopHVAC()) {\n",
+    "        for (auto ft : a_->appGHeatingFuelTypes()) {\n",
+    "          result.insert(ft);\n",
+    "        }\n",
+    "      }\n",
+    "      return {result.begin(), result.end()};\n",
+    "    }\"\"\"\n",
+    "parse_appGHeatingFuelTypeFuncBod(func_body)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "34dfc64b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class_infos = {}\n",
+    "for cpp_file in cpp_files:\n",
+    "    class_name = cpp_file.name.replace('.cpp', '')\n",
+    "\n",
+    "    with open(cpp_file, 'r') as f:\n",
+    "        content = f.read()\n",
+    "    if not 'Impl::componentType()' in content:\n",
+    "        continue\n",
+    "        \n",
+    "    lines = content.splitlines()\n",
+    "    \n",
+    "    class_info = ClassInfo(class_name=class_name)\n",
+    "\n",
+    "    i = 0\n",
+    "    while i < len(lines):\n",
+    "        if '::componentType' in lines[i]:\n",
+    "            i, func_body = get_func_body(lines, i)\n",
+    "            if m := RE_SIMPLE_COMPTYPE.match(func_body):\n",
+    "                class_info.component_type = ComponentTypeInfo(is_simple=True, simple_return=m.groups()[0])\n",
+    "            else:\n",
+    "                class_info.component_type = ComponentTypeInfo(is_simple=False, func_body=func_body)\n",
+    "        elif '::coolingFuelTypes' in lines[i]:\n",
+    "            i, func_body = get_func_body(lines, i)\n",
+    "            class_info.cooling_fuel_types = parse_coolingFuelTypeFuncBod(func_body=func_body)\n",
+    "\n",
+    "        elif '::heatingFuelTypes' in lines[i]:\n",
+    "            i, func_body = get_func_body(lines, i)\n",
+    "            class_info.heating_fuel_types = parse_heatingFuelTypeFuncBod(func_body=func_body)\n",
+    "        elif '::appGHeatingFuelTypes' in lines[i]:\n",
+    "            i, func_body = get_func_body(lines, i)\n",
+    "            class_info.appg_heating_fuel_types = parse_appGHeatingFuelTypeFuncBod(func_body=func_body)\n",
+    "        i += 1\n",
+    "    class_infos[class_name] = class_info"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "25e2806f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "ZoneHVACPackagedTerminalHeatPump,Complex,cc.coolingFuelTypes(),hc.heatingFuelTypes() + supHC.heatingFuelTypes(),hc.appGHeatingFuelTypes() + supHC.appGHeatingFuelTypes()"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "class_infos['ZoneHVACPackagedTerminalHeatPump']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b857ea67",
+   "metadata": {},
+   "source": [
+    "# Print out \"complex\" types I couldn't resolve"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a6a6ce83",
+   "metadata": {},
+   "source": [
+    "## Cooling fuel types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "d9c6486e",
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AirLoopHVACOutdoorAirSystem\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {\n",
+      "        for (auto& ft : comp.coolingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "ChillerAbsorption\n",
+      "==============\n",
+      "if (auto generatorLoop_ = generatorLoop()) {\n",
+      "        return generatorLoop_->heatingFuelTypes();  // This is done on purpose. We use heat to produce chilled water here!\n",
+      "      }\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "ChillerAbsorptionIndirect\n",
+      "==============\n",
+      "if (auto generatorLoop_ = generatorLoop()) {\n",
+      "        return generatorLoop_->heatingFuelTypes();  // This is done on purpose. We use heat to produce chilled water here!\n",
+      "      }\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "CoilSystemIntegratedHeatPumpAirSource\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "\n",
+      "      for (auto ft : spaceCoolingCoil().coolingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "\n",
+      "      for (auto ft : scwhCoil().coolingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      for (auto ft : scdwhCoolingCoil().coolingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      for (auto ft : scdwhWaterHeatingCoil().coolingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "CoilWaterHeatingAirToWaterHeatPumpWrapped\n",
+      "==============\n",
+      "//   return {};\n",
+      "    //\n",
+      "\n",
+      "\n",
+      "HeatExchangerFluidToFluid\n",
+      "==============\n",
+      "const std::string controlType = this->controlType();\n",
+      "      if (openstudio::istringEqual(controlType, \"HeatingSetpointModulated\") || openstudio::istringEqual(controlType, \"HeatingSetpointOnOff\")) {\n",
+      "        return {};\n",
+      "      }\n",
+      "      if (auto p_ = secondaryPlantLoop()) {\n",
+      "        return p_->coolingFuelTypes();\n",
+      "      }\n",
+      "\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "ThermalStorageChilledWaterStratified\n",
+      "==============\n",
+      "if (auto p_ = secondaryPlantLoop()) {\n",
+      "        return p_->coolingFuelTypes();\n",
+      "      }\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "ThermalZone\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {\n",
+      "        for (auto& ft : comp.coolingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "WaterHeaterMixed\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "\n",
+      "      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {\n",
+      "        auto plantFuelTypes = p_->coolingFuelTypes();\n",
+      "        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());\n",
+      "      }\n",
+      "\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "WaterHeaterStratified\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "\n",
+      "      // TODO: only if cap == 0?\n",
+      "      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {\n",
+      "        auto plantFuelTypes = p_->coolingFuelTypes();\n",
+      "        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());\n",
+      "      }\n",
+      "\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "for k, c in class_infos.items():\n",
+    "    if c.cooling_fuel_types.is_simple:\n",
+    "        continue\n",
+    "    \n",
+    "    print(f\"{c.class_name}\\n==============\\n{c.cooling_fuel_types.func_body}\\n\\n\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "73a570a1",
+   "metadata": {},
+   "source": [
+    "## Heating Fuel Types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "dc5bcc6d",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AirLoopHVACOutdoorAirSystem\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {\n",
+      "        for (auto& ft : comp.heatingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "CoilSystemIntegratedHeatPumpAirSource\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "\n",
+      "      for (auto ft : spaceHeatingCoil().heatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      // TODO: include dedicatedWaterHeatingCoil? The combined space cooling + water heating ones too?\n",
+      "      for (auto ft : shdwhHeatingCoil().heatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      for (auto ft : shdwhWaterHeatingCoil().heatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "CoilWaterHeatingAirToWaterHeatPumpWrapped\n",
+      "==============\n",
+      "//   return {FuelType::Electricity};\n",
+      "    //\n",
+      "\n",
+      "\n",
+      "HeatExchangerFluidToFluid\n",
+      "==============\n",
+      "const std::string controlType = this->controlType();\n",
+      "      if (openstudio::istringEqual(controlType, \"CoolingSetpointModulated\") || openstudio::istringEqual(controlType, \"CoolingSetpointOnOff\")\n",
+      "          || openstudio::istringEqual(controlType, \"CoolingDifferentialOnOff\")\n",
+      "          || openstudio::istringEqual(controlType, \"CoolingSetpointOnOffWithComponentOverride\")) {\n",
+      "        return {};\n",
+      "      }\n",
+      "      if (auto p_ = secondaryPlantLoop()) {\n",
+      "        return p_->heatingFuelTypes();\n",
+      "      }\n",
+      "\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "ThermalZone\n",
+      "==============\n",
+      "std::set<FuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {\n",
+      "        for (auto& ft : comp.heatingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "for k, c in class_infos.items():\n",
+    "    if c.heating_fuel_types.is_simple:\n",
+    "        continue\n",
+    "    \n",
+    "    print(f\"{c.class_name}\\n==============\\n{c.heating_fuel_types.func_body}\\n\\n\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a56bfe86",
+   "metadata": {},
+   "source": [
+    "## Appendix G Heating Fuel Types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "e57e33f4",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AirLoopHVACOutdoorAirSystem\n",
+      "==============\n",
+      "std::set<AppGFuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {\n",
+      "        for (auto& ft : comp.appGHeatingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "CoilSystemIntegratedHeatPumpAirSource\n",
+      "==============\n",
+      "std::set<AppGFuelType> result;\n",
+      "\n",
+      "      for (auto ft : spaceHeatingCoil().appGHeatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      // TODO: include dedicatedWaterHeatingCoil? The combined space cooling + water heating ones too?\n",
+      "      for (auto ft : shdwhHeatingCoil().appGHeatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "      for (auto ft : shdwhWaterHeatingCoil().appGHeatingFuelTypes()) {\n",
+      "        result.insert(ft);\n",
+      "      }\n",
+      "\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n",
+      "CoilWaterHeatingAirToWaterHeatPumpWrapped\n",
+      "==============\n",
+      "//   return {AppGFuelType::HeatPump};  // TODO: openstudio-standards uses Electric\n",
+      "    //\n",
+      "\n",
+      "\n",
+      "HeatExchangerFluidToFluid\n",
+      "==============\n",
+      "const std::string controlType = this->controlType();\n",
+      "      if (openstudio::istringEqual(controlType, \"CoolingSetpointModulated\") || openstudio::istringEqual(controlType, \"CoolingSetpointOnOff\")\n",
+      "          || openstudio::istringEqual(controlType, \"CoolingDifferentialOnOff\")\n",
+      "          || openstudio::istringEqual(controlType, \"CoolingSetpointOnOffWithComponentOverride\")) {\n",
+      "        return {};\n",
+      "      }\n",
+      "      if (auto p_ = secondaryPlantLoop()) {\n",
+      "        return p_->appGHeatingFuelTypes();\n",
+      "      }\n",
+      "\n",
+      "      return {};\n",
+      "\n",
+      "\n",
+      "ThermalZone\n",
+      "==============\n",
+      "std::set<AppGFuelType> result;\n",
+      "      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {\n",
+      "        for (auto& ft : comp.appGHeatingFuelTypes()) {\n",
+      "          result.insert(ft);\n",
+      "        }\n",
+      "      }\n",
+      "      return {result.begin(), result.end()};\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "for k, c in class_infos.items():\n",
+    "    if c.appg_heating_fuel_types.is_simple:\n",
+    "        continue\n",
+    "    \n",
+    "    print(f\"{c.class_name}\\n==============\\n{c.appg_heating_fuel_types.func_body}\\n\\n\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c546ca3a",
+   "metadata": {},
+   "source": [
+    "# Dump to CSV"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "c410f342",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "lines = [\",\".join(ClassInfo.header())]\n",
+    "for k, c in class_infos.items():\n",
+    "    lines.append(c.__repr__())\n",
+    "    \n",
+    "with open('FuelTypes.csv', 'w') as f:\n",
+    "    f.write(\"\\n\".join(lines) + '\\n')"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.7"
+  },
+  "toc": {
+   "base_numbering": 1,
+   "nav_menu": {},
+   "number_sections": true,
+   "sideBar": true,
+   "skip_h1_title": false,
+   "title_cell": "Table of Contents",
+   "title_sidebar": "Contents",
+   "toc_cell": false,
+   "toc_position": {},
+   "toc_section_display": true,
+   "toc_window_display": false
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/developer/ruby/SubProjectClassGenerators/ModelClassGenerator.rb b/developer/ruby/SubProjectClassGenerators/ModelClassGenerator.rb
index 91c74ac6cbe..3655f063f07 100644
--- a/developer/ruby/SubProjectClassGenerators/ModelClassGenerator.rb
+++ b/developer/ruby/SubProjectClassGenerators/ModelClassGenerator.rb
@@ -433,6 +433,18 @@ def initialize(className, baseClassName, pImpl, qobject, iddObjectType)
     @iddObjectType = iddObjectType
     @hasRealFields = false
     @hasScheduleFields = false
+
+    @derivesHVACComponent = [
+      'AirToAirComponent',
+      'HVACComponent',
+      'Mixer',
+      'SetpointManager',
+      'Splitter',
+      'StraightComponent',
+      'WaterToAirComponent',
+      'WaterToWaterComponent',
+      'ZoneHVACComponent'].include?(baseClassName)
+
     if not @iddObjectType.empty?
       require 'openstudio'
 
@@ -451,6 +463,8 @@ def initialize(className, baseClassName, pImpl, qobject, iddObjectType)
         @hasScheduleFields = true if modelObjectField.isSchedule?
       }
 
+      @objectListClassNames = @nonextensibleFields.select{|field| field.isObjectList?}.map(&:objectListClassName).uniq
+
       # Determine if the object has any autosizable fields
       @autosizedGetterNames = []
       @autosizeSetterNames = []
@@ -478,19 +492,20 @@ def cppIncludes()
       # include object list field classes
       # include IddFactory.hxx if there is a non-boolean choice field
       includeIddFactory = false
-      preamble = "// TODO: Check the following class names against object getters and setters.\n"
       @nonextensibleFields.each { |field|
         if field.isChoice? and not field.isBooleanChoice?
           includeIddFactory = true
         end
+      }
 
-        if field.isObjectList?
-          result << preamble
-          result << "#include \"" << field.objectListClassName << ".hpp\"\n"
-          result << "#include \"" << field.objectListClassName << "_Impl.hpp\"\n"
-          preamble = ""
-        end
+      preamble = "// TODO: Check the following class names against object getters and setters.\n"
+      @objectListClassNames.each { |className|
+        result << preamble
+        result << "#include \"" << className << ".hpp\"\n"
+        result << "#include \"" << className << "_Impl.hpp\"\n"
+        preamble = ""
       }
+
       if @hasScheduleFields
         result << "#include \"ScheduleTypeLimits.hpp\"\n"
         result << "#include \"ScheduleTypeRegistry.hpp\"\n"
@@ -498,7 +513,11 @@ def cppIncludes()
 
       result << "\n" if preamble == ""
 
-      result << "#include \"../utilities/core/Assert.hpp\"\n\n"
+      result << "#include \"../utilities/core/Assert.hpp\"\n"
+      if @derivesHVACComponent
+        result << "#include \"../utilities/data/DataEnums.hpp\"\n"
+      end
+      result << "\n"
 
       if includeIddFactory
         result << "#include <utilities/idd/IddFactory.hxx>\n"
@@ -535,12 +554,10 @@ def hppSubProjectForwardDeclarations
     result = String.new
     if @idfObject
       preamble = "  // TODO: Check the following class names against object getters and setters.\n"
-      @nonextensibleFields.each { |field|
-        if field.isObjectList?
-          result << preamble
-          result << "  class " << field.objectListClassName << ";\n"
-          preamble = ""
-        end
+      @objectListClassNames.each { |className|
+        result << preamble
+        result << "  class " << className << ";\n"
+        preamble = ""
       }
       result << "\n" if preamble == ""
     end
@@ -820,6 +837,13 @@ def implHppPublicMethods()
         result << "      virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;\n\n"
       end
 
+      if @derivesHVACComponent
+        result << "      virtual ComponentType componentType() const override;\n"
+        result << "      virtual std::vector<FuelType> coolingFuelTypes() const override;\n"
+        result << "      virtual std::vector<FuelType> heatingFuelTypes() const override;\n"
+        result << "      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;\n\n"
+      end
+
       result << "      //@}\n"
       result << "      /** @name Getters */\n"
       result << "      //@{\n\n"
@@ -959,6 +983,28 @@ def cppPublicMethods()
         result << "    }\n\n"
       end
 
+      if @derivesHVACComponent
+        result << "    ComponentType " << @className << "_Impl::componentType() const {\n"
+        result << "      // TODO\n"
+        result << "      return ComponentType::None;\n"
+        result << "    }\n\n"
+
+        result << "    std::vector<FuelType> " << @className << "_Impl::coolingFuelTypes() const {\n"
+        result << "      // TODO\n"
+        result << "      return {};\n"
+        result << "    }\n\n"
+
+        result << "    std::vector<FuelType> " << @className << "_Impl::heatingFuelTypes() const {\n"
+        result << "      // TODO\n"
+        result << "      return {};\n"
+        result << "    }\n\n"
+
+        result << "    std::vector<AppGFuelType> " << @className << "_Impl::appGHeatingFuelTypes() const {\n\n"
+        result << "      // TODO\n"
+        result << "      return {};\n"
+        result << "    }\n\n"
+      end
+
       # Non-extensible field getters
       @nonextensibleFields.each { |field|
 
@@ -1408,16 +1454,13 @@ def gtestIncludes()
     preamble = "// TODO: Check the following class names against object getters and setters.\n"
 
     # Check for ObjectList fields, to see which we need to include
-    @nonextensibleFields.each { |field|
-      if field.isObjectList?
-        result << preamble
-        result << "#include \"../" << field.objectListClassName << ".hpp\"\n"
-        result << "#include \"../" << field.objectListClassName << "_Impl.hpp\"\n\n"
-        preamble = ""
-      end
+    @objectListClassNames.each { |className|
+      result << preamble
+      result << "#include \"../" << className << ".hpp\"\n"
+      result << "#include \"../" << className << "_Impl.hpp\"\n\n"
+      preamble = ""
     }
 
-
     result << "using namespace openstudio;\n"
     result << "using namespace openstudio::model;\n\n"
 
@@ -1645,6 +1688,21 @@ def gtestGetterSetters
 
     result << "}\n"
 
+    if @derivesHVACComponent
+      result << "TEST_F(ModelFixture, " << className << "_HeatCoolFuelTypes) {\n"
+      result << "  Model m;\n"
+      result << "  // TODO: Check regular Ctor arguments\n"
+      result << "  " << className << " #{instanceName}(m);\n"
+      result << "  // TODO: Or if a UniqueModelObject (and make sure _Impl is included)\n"
+      result << "  // " << className << " #{instanceName} = m.getUniqueModelObject<" << className << ">();\n\n"
+
+      result << "  EXPECT_EQ(ComponentType(ComponentType::Both), #{instanceName}.componentType());\n"
+      result << "  testFuelTypeEquality({FuelType::Electricity}, #{instanceName}.coolingFuelTypes());\n"
+      result << "  testFuelTypeEquality({FuelType::Electricity, FuelType::Propane}, #{instanceName}.heatingFuelTypes());\n"
+      result << "  testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, #{instanceName}.appGHeatingFuelTypes());\n"
+      result << "}\n"
+    end
+
     return result
   end
 
diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp
index daa53d3c698..28c43a0ebc3 100644
--- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp
+++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.cpp
@@ -133,6 +133,7 @@
 #include "../../model/GeneratorMicroTurbineHeatRecovery_Impl.hpp"
 #include "../../model/GeneratorMicroTurbine.hpp"
 #include "../../model/GeneratorMicroTurbine_Impl.hpp"
+#include "../../utilities/data/DataEnums.hpp"
 
 using namespace openstudio::model;
 using namespace openstudio::energyplus;
@@ -162,6 +163,28 @@ namespace energyplus {
     return false;
   }
 
+  openstudio::energyplus::ComponentType convertOSEnumToEnum(openstudio::ComponentType compType) {
+    if (compType == openstudio::ComponentType::Cooling) {
+      return openstudio::energyplus::ComponentType::COOLING;
+    } else if (compType == openstudio::ComponentType::Heating) {
+      return openstudio::energyplus::ComponentType::HEATING;
+    } else if (compType == openstudio::ComponentType::Both) {
+      return openstudio::energyplus::ComponentType::BOTH;
+    }
+
+    return openstudio::energyplus::ComponentType::NONE;
+  }
+
+  openstudio::energyplus::ComponentType plantLoopType(const PlantLoop& plantLoop) {
+    LOG_FREE(Warn, "openstudio.energyplus.plantLoopType", "Method is deprecated. Use Loop::componentType instead");
+    return convertOSEnumToEnum(plantLoop.componentType());
+  }
+
+  openstudio::energyplus::ComponentType componentType(const openstudio::model::HVACComponent& component) {
+    LOG_FREE(Warn, "openstudio.energyplus.componentType", "Method is deprecated. Use HVACComponent::componentType instead");
+    return convertOSEnumToEnum(component.componentType());
+  }
+
   boost::optional<Node> inletNode(const PlantLoop& plantLoop, const HVACComponent& component) {
     auto comps = plantLoop.supplyComponents(plantLoop.supplyInletNode(), component);
     OS_ASSERT(comps.size() >= 2u);
@@ -365,283 +388,6 @@ namespace energyplus {
     return result;
   }
 
-  // Now using an HPP
-  // enum class ComponentType {HEATING, COOLING, BOTH, NONE};
-
-  // Forward declaration (needed because componentType and plantLoopType call each other)
-  // Now using an HPP
-  // ComponentType componentType(const HVACComponent & component);
-
-  /*
- * Check the overall type of a plantLoop by checking what is on the supply side
- * The logic is as follows:
- * * If there is only heating, no cooling, no "both": Heating
- * * If there is only cooling, no heating, no "both": Cooling
- * * If there is no cooling, no heating, no "both": None
- * * All other cases: "both"
- */
-  ComponentType plantLoopType(const PlantLoop& plantLoop) {
-
-    bool has_cooling = false;
-    bool has_heating = false;
-    bool has_both = false;
-    for (const auto& comp : subsetCastVector<HVACComponent>(plantLoop.supplyComponents())) {
-      if (componentType(comp) == ComponentType::COOLING) {
-        has_cooling = true;
-      } else if (componentType(comp) == ComponentType::HEATING) {
-        has_heating = true;
-      } else if (componentType(comp) == ComponentType::BOTH) {
-        has_both = true;
-      }
-    }
-
-    // If source side is purely cooling
-    if (has_cooling && !has_heating && !has_both) {
-      return ComponentType::COOLING;
-
-      // If source side is purely heating
-    } else if (!has_cooling && has_heating && !has_both) {
-      return ComponentType::HEATING;
-
-      // If there is nothing
-    } else if (!has_cooling && !has_heating && !has_both) {
-      return ComponentType::NONE;
-
-      // All other cases: BOTH
-    } else {
-      return ComponentType::BOTH;
-    }
-  }
-
-  ComponentType componentType(const HVACComponent& component) {
-    switch (component.iddObject().type().value()) {
-      case openstudio::IddObjectType::OS_Generator_FuelCell_ExhaustGasToWaterHeatExchanger: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_Boiler_HotWater: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_WaterHeater_Mixed: {
-        // Need to handle the case where this is used purely as a storage tank
-        auto wh = component.cast<WaterHeaterMixed>();
-        if (boost::optional<double> _cap = wh.heaterMaximumCapacity()) {
-          if (_cap.get() == 0.0) {
-            // Capacity is zero: it's a storage tank!
-            // get the Source loop
-            if (boost::optional<PlantLoop> _p = wh.secondaryPlantLoop()) {
-              // I guess we could rely on Heating/Cooling/Condenser set in the sizingPlant
-              // if ( openstudio::istringEqual(p->sizingPlant().loopType(), "Heating") { }
-              // Might be better to do a recursive call to see what type of equipment you have on the supply side of the plant loop though
-              return plantLoopType(_p.get());
-
-              // We also need to check if the tank isn't attached to a HPWH, in which case we return Heating
-              // There's some magic later that'll put the HPWH itself and not the tank on the PlantEquipmentOperation,
-              // see function operationSchemeComponent()
-            } else if (boost::optional<ZoneHVACComponent> zoneComp = wh.containingZoneHVACComponent()) {
-              // We don't have to explicitly check if it's a WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser since
-              // these are the only two types of zoneHVACComponent that could have a WaterHeater object, but this might change in the future
-              IddObjectType zoneCompIdd = zoneComp->iddObjectType();
-              if ((zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump)
-                  || (zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump_WrappedCondenser)) {
-                return ComponentType::HEATING;
-              }
-            } else {
-              // It isn't connected to a source side, and has zero capacity, and not part of HPWH => it's a buffer tank => NONE
-              return ComponentType::NONE;
-            }  // End if has source loop
-
-          } else {
-            // If there is a capacity, and it's not zero, it's heating
-            return ComponentType::HEATING;
-          }  // End cap == 0
-
-        } else {
-          // If autosize, then it's Heating
-          return ComponentType::HEATING;
-        }  // end has a heater capacity
-      }
-      case openstudio::IddObjectType::OS_WaterHeater_Stratified: {
-        // Need to handle the case where this is used purely as a storage tank
-        auto wh = component.cast<WaterHeaterStratified>();
-
-        if (wh.heater2Capacity() == 0.0) {
-          if (boost::optional<double> _cap = wh.heater1Capacity()) {
-            if (_cap.get() == 0.0) {
-              // Capacity is zero: it's a storage tank!
-              // get the Source loop
-              if (boost::optional<PlantLoop> _p = wh.secondaryPlantLoop()) {
-                // Here we go check what's on the supply side of the secondary plantLoop
-                return plantLoopType(_p.get());
-
-                // If it's attached to a HPWH, it's Heating (see detailed note for WaterHeaterMixed above)
-              } else if (boost::optional<ZoneHVACComponent> zoneComp = wh.containingZoneHVACComponent()) {
-                IddObjectType zoneCompIdd = zoneComp->iddObjectType();
-                if ((zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump)
-                    || (zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump_WrappedCondenser)) {
-                  return ComponentType::HEATING;
-                }
-              } else {
-                // It isn't connected to a source side, and has zero capacity, and not part of HPWH => it's a buffer tank => NONE
-                return ComponentType::NONE;
-              }
-            }
-          }
-        }
-
-        // If we reach here, it means there is at least one heater that has a capacity non zero, so it's a HEATING type
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_DistrictHeating: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_CentralHeatPumpSystem: {
-        // Note (JM): This really depends on which loop is calling this...
-
-        // This component has a tertiary loop, and is placed on the supply side of TWO loops: Heating and Cooling
-        // If it's the supplyLoop (= cooling), we should probably have a PlantEquipmentOperation::CoolingLoad
-        // If it's the tertiaryLoop (= heating), PlantEquipmentOperation::HeatingLoad
-        // Returning BOTH will place it on a PlantEquipmentOperation::Uncontrolled
-
-        // As a result, this is handled in coolingComponents() and heatingComponents() directly
-        return ComponentType::NONE;
-      }
-      case openstudio::IddObjectType::OS_Chiller_Electric_ASHRAE205: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_Chiller_Electric_EIR: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_Chiller_Electric_ReformulatedEIR: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_Chiller_Absorption_Indirect: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_Chiller_Absorption: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_ThermalStorage_ChilledWater_Stratified: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_ThermalStorage_Ice_Detailed: {
-        // TODO: Are you sure about this @kbenne?
-        return ComponentType::BOTH;
-      }
-      case openstudio::IddObjectType::OS_DistrictCooling: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_CoolingTower_SingleSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_CoolingTower_VariableSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_CoolingTower_TwoSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_EvaporativeFluidCooler_SingleSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_EvaporativeFluidCooler_TwoSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_FluidCooler_SingleSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_FluidCooler_TwoSpeed: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_GroundHeatExchanger_Vertical: {
-        return ComponentType::BOTH;
-      }
-      case openstudio::IddObjectType::OS_GroundHeatExchanger_HorizontalTrench: {
-        return ComponentType::BOTH;
-      }
-      case openstudio::IddObjectType::OS_HeatExchanger_FluidToFluid: {
-        // "Smart" defaults instead of ComponentType::BOTH;
-        auto hx = component.cast<HeatExchangerFluidToFluid>();
-
-        std::string controlType = hx.controlType();
-
-        if (openstudio::istringEqual(controlType, "HeatingSetpointModulated") || openstudio::istringEqual(controlType, "HeatingSetpointOnOff")) {
-          return ComponentType::HEATING;
-
-        } else if (openstudio::istringEqual(controlType, "CoolingSetpointModulated") || openstudio::istringEqual(controlType, "CoolingSetpointOnOff")
-                   || openstudio::istringEqual(controlType, "CoolingDifferentialOnOff")
-                   || openstudio::istringEqual(controlType, "CoolingSetpointOnOffWithComponentOverride")) {
-          return ComponentType::COOLING;
-
-        } else if (openstudio::istringEqual(controlType, "DualDeadbandSetpointModulated")
-                   || openstudio::istringEqual(controlType, "DualDeadbandSetpointOnOff")) {
-          return ComponentType::BOTH;
-        } else if (openstudio::istringEqual(controlType, "UncontrolledOn")) {
-          // Here we go check what's on the supply side of the secondary plantLoop if there is one
-          // It's going to crash if there isn't a secondary plant Loop anyways
-          // get the Source loop
-          if (boost::optional<PlantLoop> _p = hx.secondaryPlantLoop()) {
-            return plantLoopType(_p.get());
-          } else {
-            // It isn't connected to a source side (beats the point of the HX)
-            return ComponentType::NONE;
-          }  // End if has source loop
-
-        } else {
-          // For OperationSchemeModulated and OperationSchemeOnOff
-
-          // TODO: would need to open a log channel
-          //Log(Debug, "HeatExchangerFluidToFluid '" << hx.nameString() << "' doesn't have a "
-          //"controlType ('" << controlType << "') that allows us to specify whether "
-          //"it's heating or cooling, setting to ComponentType::BOTH");
-          return ComponentType::BOTH;
-        }
-      }
-      case openstudio::IddObjectType::OS_SolarCollector_FlatPlate_PhotovoltaicThermal: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_SolarCollector_FlatPlate_Water: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_SolarCollector_IntegralCollectorStorage: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_PlantComponent_TemperatureSource: {
-        //TODO can this be inferred from PlantLoadingMode?
-        return ComponentType::BOTH;
-      }
-      case openstudio::IddObjectType::OS_PlantComponent_UserDefined: {
-        return ComponentType::BOTH;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_WaterToWater_EquationFit_Heating: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_WaterToWater_EquationFit_Cooling: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_PlantLoop_EIR_Heating: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_PlantLoop_EIR_Cooling: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_AirToWater_FuelFired_Heating: {
-        return ComponentType::HEATING;
-      }
-      case openstudio::IddObjectType::OS_HeatPump_AirToWater_FuelFired_Cooling: {
-        return ComponentType::COOLING;
-      }
-      case openstudio::IddObjectType::OS_Generator_MicroTurbine_HeatRecovery: {
-        // Maybe that should be both, in the case of an absorption chiller?
-        // Also, should maybe check if it's in mode FollowThermal or FollowThermalLimitElectrical?
-        // If not in these two modes, it doesn't care and just runs. Also, it's typically on the demand Side, and this method
-        // is only called on the supply side
-        return ComponentType::HEATING;
-      }
-      default: {
-        return ComponentType::NONE;
-      }
-    }
-  }
-
   // Some plant components air in a containingHVACComponent() and it is that
   // container which needs to go on the plant operation scheme. Here is a filter to
   // figure that out.
@@ -703,7 +449,7 @@ namespace energyplus {
         }
 
         // Regular case
-      } else if (componentType(comp) == ComponentType::COOLING) {
+      } else if (comp.componentType() == openstudio::ComponentType::Cooling) {
         result.push_back(operationSchemeComponent(comp));
       }
     }
@@ -725,7 +471,7 @@ namespace energyplus {
         }
 
         // Regular case
-      } else if (componentType(comp) == ComponentType::HEATING) {
+      } else if (comp.componentType() == openstudio::ComponentType::Heating) {
         result.push_back(operationSchemeComponent(comp));
       }
     }
@@ -737,7 +483,7 @@ namespace energyplus {
     std::vector<HVACComponent> result;
 
     for (const auto& comp : subsetCastVector<HVACComponent>(plantLoop.supplyComponents())) {
-      if ((componentType(comp) == ComponentType::BOTH) && !(_isSetpointComponent(plantLoop, comp))) {
+      if ((comp.componentType() == openstudio::ComponentType::Both) && !(_isSetpointComponent(plantLoop, comp))) {
         result.push_back(operationSchemeComponent(comp));
       }
     }
@@ -803,17 +549,13 @@ namespace energyplus {
           } else {
             eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::ComponentFlowRate, "Autosize");
           }
-          auto t_componentType = componentType(setpointComponent);
-          switch (t_componentType) {
-            case ComponentType::HEATING:
-              eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Heating");
-              break;
-            case ComponentType::COOLING:
-              eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Cooling");
-              break;
-            default:
-              eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Dual");
-              break;
+          auto t_componentType = setpointComponent.componentType();
+          if (t_componentType == openstudio::ComponentType::Heating) {
+            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Heating");
+          } else if (t_componentType == openstudio::ComponentType::Cooling) {
+            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Cooling");
+          } else {
+            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType, "Dual");
           }
         }
       }
diff --git a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.hpp b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.hpp
index 8abee725b6f..429dc4d855a 100644
--- a/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.hpp
+++ b/src/energyplus/ForwardTranslator/ForwardTranslatePlantEquipmentOperationSchemes.hpp
@@ -33,9 +33,12 @@
 #include <vector>
 #include <boost/optional.hpp>
 #include "../EnergyPlusAPI.hpp"
+#include "../../utilities/core/Deprecated.hpp"
 
 namespace openstudio {
 
+class ComponentType;
+
 namespace model {
 
   class ModelObject;
@@ -55,7 +58,7 @@ namespace energyplus {
     NONE
   };
 
-  ENERGYPLUS_API ComponentType componentType(const openstudio::model::HVACComponent& component);
+  OS_DEPRECATED ENERGYPLUS_API openstudio::energyplus::ComponentType componentType(const openstudio::model::HVACComponent& component);
 
   bool _isSetpointComponent(const openstudio::model::PlantLoop& plantLoop, const openstudio::model::ModelObject& comp);
 
@@ -75,7 +78,7 @@ namespace energyplus {
    * * If there is no cooling, no heating, no "both": None
    * * All other cases: "both"
    */
-  ENERGYPLUS_API ComponentType plantLoopType(const openstudio::model::PlantLoop& plantLoop);
+  OS_DEPRECATED ENERGYPLUS_API openstudio::energyplus::ComponentType plantLoopType(const openstudio::model::PlantLoop& plantLoop);
 
   /* Some plant components air in a containingHVACComponent() and it is that
    * container which needs to go on the plant operation scheme. Here is a filter to figure that out.
diff --git a/src/energyplus/Test/PlantEquipmentOperationSchemes_GTest.cpp b/src/energyplus/Test/PlantEquipmentOperationSchemes_GTest.cpp
index 6465b9f303a..4355b7f6804 100644
--- a/src/energyplus/Test/PlantEquipmentOperationSchemes_GTest.cpp
+++ b/src/energyplus/Test/PlantEquipmentOperationSchemes_GTest.cpp
@@ -636,158 +636,158 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_PlantEquipmentOperationSchemes_compo
 
   {
     EvaporativeFluidCoolerTwoSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     GeneratorFuelCellExhaustGasToWaterHeatExchanger obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     BoilerHotWater obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     DistrictHeating obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     ChillerElectricEIR obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     ChillerElectricReformulatedEIR obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     ChillerAbsorptionIndirect obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     ChillerAbsorption obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     ThermalStorageChilledWaterStratified obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     DistrictCooling obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     CoolingTowerSingleSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     CoolingTowerVariableSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     CoolingTowerTwoSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     EvaporativeFluidCoolerSingleSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     EvaporativeFluidCoolerTwoSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     FluidCoolerSingleSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     FluidCoolerTwoSpeed obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     GroundHeatExchangerVertical obj(m);
-    EXPECT_EQ(ComponentType::BOTH, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::BOTH, openstudio::energyplus::componentType(obj));
   }
 
   {
     GroundHeatExchangerHorizontalTrench obj(m);
-    EXPECT_EQ(ComponentType::BOTH, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::BOTH, openstudio::energyplus::componentType(obj));
   }
 
   {
     SolarCollectorFlatPlatePhotovoltaicThermal obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     SolarCollectorFlatPlateWater obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     SolarCollectorIntegralCollectorStorage obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     PlantComponentUserDefined obj(m);
-    EXPECT_EQ(ComponentType::BOTH, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::BOTH, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpWaterToWaterEquationFitHeating obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpWaterToWaterEquationFitCooling obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpPlantLoopEIRHeating obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpPlantLoopEIRCooling obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpAirToWaterFuelFiredHeating obj(m);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     HeatPumpAirToWaterFuelFiredCooling obj(m);
-    EXPECT_EQ(ComponentType::COOLING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::COOLING, openstudio::energyplus::componentType(obj));
   }
 
   {
     GeneratorMicroTurbine chp(m);
     GeneratorMicroTurbineHeatRecovery obj(m, chp);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     PlantComponentTemperatureSource obj(m);
-    EXPECT_EQ(ComponentType::BOTH, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::BOTH, openstudio::energyplus::componentType(obj));
   }
 
   /***********************************************
@@ -798,11 +798,11 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_PlantEquipmentOperationSchemes_compo
 
     // No Capacity, not on a loop, not in a HPWH => NONE
     obj.setHeaterMaximumCapacity(0.0);
-    EXPECT_EQ(ComponentType::NONE, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::NONE, openstudio::energyplus::componentType(obj));
 
     // If it has a capacity, it's heating
     obj.setHeaterMaximumCapacity(1000);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
@@ -810,22 +810,22 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_PlantEquipmentOperationSchemes_compo
     // If it has a capacity, it's heating
     obj.setHeater1Capacity(0.0);
     obj.setHeater2Capacity(0.0);
-    EXPECT_EQ(ComponentType::NONE, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::NONE, openstudio::energyplus::componentType(obj));
 
     // Any of the two heaters has a capacity? => HEATING
     obj.setHeater1Capacity(100.0);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
     obj.setHeater1Capacity(0.0);
-    EXPECT_EQ(ComponentType::NONE, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::NONE, openstudio::energyplus::componentType(obj));
 
     obj.setHeater2Capacity(100.0);
-    EXPECT_EQ(ComponentType::HEATING, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::HEATING, openstudio::energyplus::componentType(obj));
   }
 
   {
     // This is a special case for CentralHeatPumpSystem, it's handled later
     CentralHeatPumpSystem obj(m);
-    EXPECT_EQ(ComponentType::NONE, openstudio::energyplus::componentType(obj));
+    EXPECT_EQ(openstudio::energyplus::ComponentType::NONE, openstudio::energyplus::componentType(obj));
   }
 
   {
@@ -836,21 +836,21 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_PlantEquipmentOperationSchemes_compo
   {
     HeatExchangerFluidToFluid obj(m);
 
-    std::vector<std::pair<std::string, ComponentType>> expectedResults{
-      {"UncontrolledOn", ComponentType::NONE},  // Not on a plant loop
+    std::vector<std::pair<std::string, openstudio::energyplus::ComponentType>> expectedResults{
+      {"UncontrolledOn", openstudio::energyplus::ComponentType::NONE},  // Not on a plant loop
 
-      {"HeatingSetpointModulated", ComponentType::HEATING},
-      {"HeatingSetpointOnOff", ComponentType::HEATING},
+      {"HeatingSetpointModulated", openstudio::energyplus::ComponentType::HEATING},
+      {"HeatingSetpointOnOff", openstudio::energyplus::ComponentType::HEATING},
 
-      {"CoolingSetpointModulated", ComponentType::COOLING},
-      {"CoolingSetpointOnOff", ComponentType::COOLING},
-      {"CoolingDifferentialOnOff", ComponentType::COOLING},
-      {"CoolingSetpointOnOffWithComponentOverride", ComponentType::COOLING},
+      {"CoolingSetpointModulated", openstudio::energyplus::ComponentType::COOLING},
+      {"CoolingSetpointOnOff", openstudio::energyplus::ComponentType::COOLING},
+      {"CoolingDifferentialOnOff", openstudio::energyplus::ComponentType::COOLING},
+      {"CoolingSetpointOnOffWithComponentOverride", openstudio::energyplus::ComponentType::COOLING},
 
-      {"OperationSchemeModulated", ComponentType::BOTH},
-      {"OperationSchemeOnOff", ComponentType::BOTH},
-      {"DualDeadbandSetpointModulated", ComponentType::BOTH},
-      {"DualDeadbandSetpointOnOff", ComponentType::BOTH},
+      {"OperationSchemeModulated", openstudio::energyplus::ComponentType::BOTH},
+      {"OperationSchemeOnOff", openstudio::energyplus::ComponentType::BOTH},
+      {"DualDeadbandSetpointModulated", openstudio::energyplus::ComponentType::BOTH},
+      {"DualDeadbandSetpointOnOff", openstudio::energyplus::ComponentType::BOTH},
     };
 
     for (const auto& [controlType, compType] : expectedResults) {
diff --git a/src/model/AirConditionerVariableRefrigerantFlow.cpp b/src/model/AirConditionerVariableRefrigerantFlow.cpp
index 81103ca75fd..ced6c829c91 100644
--- a/src/model/AirConditionerVariableRefrigerantFlow.cpp
+++ b/src/model/AirConditionerVariableRefrigerantFlow.cpp
@@ -53,14 +53,15 @@
 #include "PlantLoop_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
-#include <utilities/idd/OS_AirConditioner_VariableRefrigerantFlow_FieldEnums.hxx>
-#include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/core/Containers.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
+#include <utilities/idd/OS_AirConditioner_VariableRefrigerantFlow_FieldEnums.hxx>
+#include <utilities/idd/IddEnums.hxx>
+
 namespace openstudio {
 
 namespace model {
@@ -1802,6 +1803,48 @@ namespace model {
       return ok;
     }
 
+    ComponentType AirConditionerVariableRefrigerantFlow_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlow_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType(fuelType()));
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlow_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType(fuelType()));
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirConditionerVariableRefrigerantFlow_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      auto fType = FuelType(fuelType());
+      if (fType == FuelType::Electricity) {
+        result.insert(AppGFuelType::HeatPump);
+      } else {
+        result.insert(convertFuelTypeToAppG(fType));
+      }
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirConditionerVariableRefrigerantFlow::AirConditionerVariableRefrigerantFlow(const Model& model)
diff --git a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl.cpp b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl.cpp
index c5eb3b8f469..8e2485927a1 100644
--- a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl.cpp
+++ b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl.cpp
@@ -60,6 +60,7 @@
 #include "ScheduleTypeRegistry.hpp"
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
@@ -911,6 +912,22 @@ namespace model {
       return getAutosizedValue("Design Size Rated Total Heating Capacity", "W");
     }
 
+    ComponentType AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   AirConditionerVariableRefrigerantFlowFluidTemperatureControl::AirConditionerVariableRefrigerantFlowFluidTemperatureControl(const Model& model)
diff --git a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR.cpp b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR.cpp
index 05e1b482b38..20f8b86e8e7 100644
--- a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR.cpp
+++ b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR.cpp
@@ -59,6 +59,7 @@
 #include "ScheduleTypeRegistry.hpp"
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
@@ -1181,6 +1182,22 @@ namespace model {
       return getAutosizedValue("Design Size Rated Total Heating Capacity", "W");
     }
 
+    ComponentType AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR::AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR(const Model& model)
diff --git a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl.hpp b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl.hpp
index c3e997ee8e5..2b3dcc361ff 100644
--- a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl.hpp
+++ b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl.hpp
@@ -88,6 +88,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
index 6cc37da4d1a..15d24e69819 100644
--- a/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
+++ b/src/model/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
@@ -88,6 +88,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirConditionerVariableRefrigerantFlow_Impl.hpp b/src/model/AirConditionerVariableRefrigerantFlow_Impl.hpp
index 7a992cacacc..36d3a718f04 100644
--- a/src/model/AirConditionerVariableRefrigerantFlow_Impl.hpp
+++ b/src/model/AirConditionerVariableRefrigerantFlow_Impl.hpp
@@ -89,6 +89,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
 
       Schedule availabilitySchedule() const;
diff --git a/src/model/AirLoopHVACOutdoorAirSystem.cpp b/src/model/AirLoopHVACOutdoorAirSystem.cpp
index dd192dab36d..1fe560ea546 100644
--- a/src/model/AirLoopHVACOutdoorAirSystem.cpp
+++ b/src/model/AirLoopHVACOutdoorAirSystem.cpp
@@ -50,15 +50,18 @@
 #include "ModelExtensibleGroup.hpp"
 #include "SetpointManager.hpp"
 #include "SetpointManager_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/core/Compare.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/IdfExtensibleGroup.hpp"
+
 #include <utilities/idd/OS_AirLoopHVAC_OutdoorAirSystem_FieldEnums.hxx>
 #include <utilities/idd/OS_AvailabilityManagerAssignmentList_FieldEnums.hxx>
 #include <utilities/idd/OS_Controller_OutdoorAir_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include <utility>
 
-#include "../utilities/core/Compare.hpp"
-#include "../utilities/core/Assert.hpp"
+#include <utility>
 
 namespace openstudio {
 
@@ -612,6 +615,61 @@ namespace model {
       }
     }
 
+    ComponentType AirLoopHVACOutdoorAirSystem_Impl::componentType() const {
+      bool has_cooling = false;
+      bool has_heating = false;
+      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {
+        auto compType = comp.componentType();
+        if (compType == ComponentType::Cooling) {
+          has_cooling = true;
+        } else if (compType == ComponentType::Heating) {
+          has_heating = true;
+        } else if (compType == ComponentType::Both) {
+          has_cooling = true;
+          has_heating = true;
+        }
+      }
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACOutdoorAirSystem_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {
+        for (auto& ft : comp.coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirLoopHVACOutdoorAirSystem_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {
+        for (auto& ft : comp.heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACOutdoorAirSystem_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(components())) {
+        for (auto& ft : comp.appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   // create a new AirLoopHVACOutdoorAirSystem object in the model's workspace
diff --git a/src/model/AirLoopHVACOutdoorAirSystem_Impl.hpp b/src/model/AirLoopHVACOutdoorAirSystem_Impl.hpp
index 1a81e173e64..958b2dfa993 100644
--- a/src/model/AirLoopHVACOutdoorAirSystem_Impl.hpp
+++ b/src/model/AirLoopHVACOutdoorAirSystem_Impl.hpp
@@ -112,6 +112,11 @@ namespace model {
 
       boost::optional<AirLoopHVACDedicatedOutdoorAirSystem> airLoopHVACDedicatedOutdoorAirSystem() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.AirLoopHVACOutdoorAirSystem");
 
diff --git a/src/model/AirLoopHVACReturnPlenum.cpp b/src/model/AirLoopHVACReturnPlenum.cpp
index 8e4aeb8eaa8..6b26307f605 100644
--- a/src/model/AirLoopHVACReturnPlenum.cpp
+++ b/src/model/AirLoopHVACReturnPlenum.cpp
@@ -51,6 +51,9 @@
 #include "Connection_Impl.hpp"
 #include "ZoneHVACIdealLoadsAirSystem.hpp"
 #include "ZoneHVACIdealLoadsAirSystem_Impl.hpp"
+
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_AirLoopHVAC_ReturnPlenum_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
@@ -366,6 +369,22 @@ namespace model {
       return result;
     }
 
+    ComponentType AirLoopHVACReturnPlenum_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACReturnPlenum_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> AirLoopHVACReturnPlenum_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACReturnPlenum_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   AirLoopHVACReturnPlenum::AirLoopHVACReturnPlenum(const Model& model) : Mixer(AirLoopHVACReturnPlenum::iddObjectType(), model) {
diff --git a/src/model/AirLoopHVACReturnPlenum_Impl.hpp b/src/model/AirLoopHVACReturnPlenum_Impl.hpp
index c2e12a19bbc..18761fb2a22 100644
--- a/src/model/AirLoopHVACReturnPlenum_Impl.hpp
+++ b/src/model/AirLoopHVACReturnPlenum_Impl.hpp
@@ -59,6 +59,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       boost::optional<ThermalZone> thermalZone() const;
 
       bool setThermalZone(const boost::optional<ThermalZone>& thermalZone);
diff --git a/src/model/AirLoopHVACSupplyPlenum.cpp b/src/model/AirLoopHVACSupplyPlenum.cpp
index 42c6fb8a01a..9a0908468a6 100644
--- a/src/model/AirLoopHVACSupplyPlenum.cpp
+++ b/src/model/AirLoopHVACSupplyPlenum.cpp
@@ -45,6 +45,9 @@
 #include "Node_Impl.hpp"
 #include "AirTerminalSingleDuctConstantVolumeNoReheat.hpp"
 #include "AirTerminalSingleDuctConstantVolumeNoReheat_Impl.hpp"
+
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_AirLoopHVAC_SupplyPlenum_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
@@ -275,6 +278,22 @@ namespace model {
       return Splitter_Impl::remove();
     }
 
+    ComponentType AirLoopHVACSupplyPlenum_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACSupplyPlenum_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> AirLoopHVACSupplyPlenum_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACSupplyPlenum_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   AirLoopHVACSupplyPlenum::AirLoopHVACSupplyPlenum(const Model& model) : Splitter(AirLoopHVACSupplyPlenum::iddObjectType(), model) {
diff --git a/src/model/AirLoopHVACSupplyPlenum_Impl.hpp b/src/model/AirLoopHVACSupplyPlenum_Impl.hpp
index e9775e58551..59ea22babd7 100644
--- a/src/model/AirLoopHVACSupplyPlenum_Impl.hpp
+++ b/src/model/AirLoopHVACSupplyPlenum_Impl.hpp
@@ -57,6 +57,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       boost::optional<ThermalZone> thermalZone() const;
 
       bool setThermalZone(const boost::optional<ThermalZone>& thermalZone);
diff --git a/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp b/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp
index 155da1bd50f..b58e4e7e774 100644
--- a/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp
+++ b/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.cpp
@@ -39,12 +39,12 @@
 #include "Node_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypass_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -663,6 +663,22 @@ namespace model {
       return types;
     }
 
+    ComponentType AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass(const Model& model, const HVACComponent& fan,
diff --git a/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl.hpp b/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl.hpp
index f41e6a7c02a..d9595ee6d2b 100644
--- a/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl.hpp
+++ b/src/model/AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass_Impl.hpp
@@ -67,6 +67,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirLoopHVACUnitaryHeatPumpAirToAir.cpp b/src/model/AirLoopHVACUnitaryHeatPumpAirToAir.cpp
index c7caa8b9993..66407458d90 100644
--- a/src/model/AirLoopHVACUnitaryHeatPumpAirToAir.cpp
+++ b/src/model/AirLoopHVACUnitaryHeatPumpAirToAir.cpp
@@ -63,13 +63,13 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_AirLoopHVAC_UnitaryHeatPump_AirToAir_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -694,6 +694,36 @@ namespace model {
       return types;
     }
 
+    ComponentType AirLoopHVACUnitaryHeatPumpAirToAir_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatPumpAirToAir_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatPumpAirToAir_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACUnitaryHeatPumpAirToAir_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirLoopHVACUnitaryHeatPumpAirToAir::AirLoopHVACUnitaryHeatPumpAirToAir(const Model& model, Schedule& availabilitySchedule, HVACComponent& supplyFan,
diff --git a/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp b/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp
index 91487e26708..c34bd24efa0 100644
--- a/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp
+++ b/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.cpp
@@ -37,12 +37,13 @@
 #include "ThermalZone_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_AirLoopHVAC_UnitaryHeatPump_AirToAir_MultiSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -770,6 +771,37 @@ namespace model {
       return types;
     }
 
+    ComponentType AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl::componentType() const {
+
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed(const Model& model, const HVACComponent& fan,
diff --git a/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl.hpp b/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl.hpp
index 536245b346a..7e73550f1ec 100644
--- a/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl.hpp
+++ b/src/model/AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_Impl.hpp
@@ -67,6 +67,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirLoopHVACUnitaryHeatPumpAirToAir_Impl.hpp b/src/model/AirLoopHVACUnitaryHeatPumpAirToAir_Impl.hpp
index d4ebbe61459..5ca1cc9e20a 100644
--- a/src/model/AirLoopHVACUnitaryHeatPumpAirToAir_Impl.hpp
+++ b/src/model/AirLoopHVACUnitaryHeatPumpAirToAir_Impl.hpp
@@ -82,6 +82,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirLoopHVACUnitarySystem.cpp b/src/model/AirLoopHVACUnitarySystem.cpp
index b5362fa9391..a6706e5ea39 100644
--- a/src/model/AirLoopHVACUnitarySystem.cpp
+++ b/src/model/AirLoopHVACUnitarySystem.cpp
@@ -46,15 +46,13 @@
 #include "UnitarySystemPerformanceMultispeed.hpp"
 #include "UnitarySystemPerformanceMultispeed_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_AirLoopHVAC_UnitarySystem_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -1327,6 +1325,62 @@ namespace model {
       return types;
     }
 
+    ComponentType AirLoopHVACUnitarySystem_Impl::componentType() const {
+      const bool has_cooling = coolingCoil().is_initialized();
+      const bool has_heating = heatingCoil().is_initialized();
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitarySystem_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirLoopHVACUnitarySystem_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto supHC_ = supplementalHeatingCoil()) {
+        for (auto ft : supHC_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACUnitarySystem_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto supHC_ = supplementalHeatingCoil()) {
+        for (auto ft : supHC_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirLoopHVACUnitarySystem::AirLoopHVACUnitarySystem(const Model& model) : ZoneHVACComponent(AirLoopHVACUnitarySystem::iddObjectType(), model) {
diff --git a/src/model/AirLoopHVACUnitarySystem_Impl.hpp b/src/model/AirLoopHVACUnitarySystem_Impl.hpp
index ef3582f2646..60de9860e06 100644
--- a/src/model/AirLoopHVACUnitarySystem_Impl.hpp
+++ b/src/model/AirLoopHVACUnitarySystem_Impl.hpp
@@ -81,6 +81,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirLoopHVACZoneMixer.cpp b/src/model/AirLoopHVACZoneMixer.cpp
index 83140c632b2..54b6cd0f0d7 100644
--- a/src/model/AirLoopHVACZoneMixer.cpp
+++ b/src/model/AirLoopHVACZoneMixer.cpp
@@ -40,6 +40,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -141,6 +142,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType AirLoopHVACZoneMixer_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACZoneMixer_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> AirLoopHVACZoneMixer_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACZoneMixer_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new AirLoopHVACZoneMixer object in the model's workspace
diff --git a/src/model/AirLoopHVACZoneMixer_Impl.hpp b/src/model/AirLoopHVACZoneMixer_Impl.hpp
index d814bfb6ada..d888e654cff 100644
--- a/src/model/AirLoopHVACZoneMixer_Impl.hpp
+++ b/src/model/AirLoopHVACZoneMixer_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       boost::optional<AirflowNetworkDistributionNode> airflowNetworkDistributionNode() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.AirLoopHVACZoneMixer");
     };
diff --git a/src/model/AirLoopHVACZoneSplitter.cpp b/src/model/AirLoopHVACZoneSplitter.cpp
index 0f9a4f53aa8..e8bddbbda5e 100644
--- a/src/model/AirLoopHVACZoneSplitter.cpp
+++ b/src/model/AirLoopHVACZoneSplitter.cpp
@@ -43,6 +43,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -168,6 +169,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType AirLoopHVACZoneSplitter_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirLoopHVACZoneSplitter_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> AirLoopHVACZoneSplitter_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirLoopHVACZoneSplitter_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   AirLoopHVACZoneSplitter::AirLoopHVACZoneSplitter(const Model& model) : Splitter(AirLoopHVACZoneSplitter::iddObjectType(), model) {
diff --git a/src/model/AirLoopHVACZoneSplitter_Impl.hpp b/src/model/AirLoopHVACZoneSplitter_Impl.hpp
index 51743c1b944..1067ce578b7 100644
--- a/src/model/AirLoopHVACZoneSplitter_Impl.hpp
+++ b/src/model/AirLoopHVACZoneSplitter_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       boost::optional<AirflowNetworkDistributionNode> airflowNetworkDistributionNode() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.AirLoopHVACZoneSplitter");
     };
diff --git a/src/model/AirTerminalDualDuctConstantVolume.cpp b/src/model/AirTerminalDualDuctConstantVolume.cpp
index ee007ebb53b..6c1d96588cf 100644
--- a/src/model/AirTerminalDualDuctConstantVolume.cpp
+++ b/src/model/AirTerminalDualDuctConstantVolume.cpp
@@ -46,8 +46,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_AirTerminal_DualDuct_ConstantVolume_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -226,6 +226,35 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalDualDuctConstantVolume_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctConstantVolume_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctConstantVolume_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalDualDuctConstantVolume_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalDualDuctConstantVolume::AirTerminalDualDuctConstantVolume(const Model& model)
diff --git a/src/model/AirTerminalDualDuctConstantVolume_Impl.hpp b/src/model/AirTerminalDualDuctConstantVolume_Impl.hpp
index 9b13d55d541..4d9e8061682 100644
--- a/src/model/AirTerminalDualDuctConstantVolume_Impl.hpp
+++ b/src/model/AirTerminalDualDuctConstantVolume_Impl.hpp
@@ -70,6 +70,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalDualDuctVAV.cpp b/src/model/AirTerminalDualDuctVAV.cpp
index 2649e995721..80791a93522 100644
--- a/src/model/AirTerminalDualDuctVAV.cpp
+++ b/src/model/AirTerminalDualDuctVAV.cpp
@@ -43,8 +43,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_AirTerminal_DualDuct_VAV_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -295,6 +295,35 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalDualDuctVAV_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctVAV_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctVAV_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalDualDuctVAV_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalDualDuctVAV::AirTerminalDualDuctVAV(const Model& model) : Mixer(AirTerminalDualDuctVAV::iddObjectType(), model) {
diff --git a/src/model/AirTerminalDualDuctVAVOutdoorAir.cpp b/src/model/AirTerminalDualDuctVAVOutdoorAir.cpp
index 834c80956c7..9d0e8df661b 100644
--- a/src/model/AirTerminalDualDuctVAVOutdoorAir.cpp
+++ b/src/model/AirTerminalDualDuctVAVOutdoorAir.cpp
@@ -48,8 +48,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_AirTerminal_DualDuct_VAV_OutdoorAir_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -287,6 +287,35 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalDualDuctVAVOutdoorAir_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctVAVOutdoorAir_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalDualDuctVAVOutdoorAir_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalDualDuctVAVOutdoorAir_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalDualDuctVAVOutdoorAir::AirTerminalDualDuctVAVOutdoorAir(const Model& model)
diff --git a/src/model/AirTerminalDualDuctVAVOutdoorAir_Impl.hpp b/src/model/AirTerminalDualDuctVAVOutdoorAir_Impl.hpp
index b22d732aeb6..12ac5379c8e 100644
--- a/src/model/AirTerminalDualDuctVAVOutdoorAir_Impl.hpp
+++ b/src/model/AirTerminalDualDuctVAVOutdoorAir_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalDualDuctVAV_Impl.hpp b/src/model/AirTerminalDualDuctVAV_Impl.hpp
index 5843b44f165..4d66347a46f 100644
--- a/src/model/AirTerminalDualDuctVAV_Impl.hpp
+++ b/src/model/AirTerminalDualDuctVAV_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam.cpp b/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam.cpp
index 67f62f8d0ba..de3392ca4a9 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam.cpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam.cpp
@@ -58,8 +58,8 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_ConstantVolume_CooledBeam_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -609,6 +609,45 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctConstantVolumeCooledBeam_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Heating)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeCooledBeam_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : coilCoolingCooledBeam().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeCooledBeam_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctConstantVolumeCooledBeam_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctConstantVolumeCooledBeam::AirTerminalSingleDuctConstantVolumeCooledBeam(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam_Impl.hpp b/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam_Impl.hpp
index d0a38140a99..fb739b7fbce 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeCooledBeam_Impl.hpp
@@ -81,6 +81,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam.cpp b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam.cpp
index eaf53f59db2..7dcb1c3695e 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam.cpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam.cpp
@@ -60,9 +60,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_AirTerminal_SingleDuct_ConstantVolume_FourPipeBeam_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -631,6 +630,76 @@ namespace model {
       return node;
     }
 
+    ComponentType AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl::componentType() const {
+      bool has_cooling = coolingCoil().is_initialized();
+      bool has_heating = heatingCoil().is_initialized();
+      if (auto a_ = airLoopHVAC()) {
+        auto compType = a_->componentType();
+        if (compType == ComponentType::Cooling) {
+          has_cooling = true;
+        } else if (compType == ComponentType::Heating) {
+          has_heating = true;
+        } else if (compType == ComponentType::Both) {
+          has_heating = true;
+          has_cooling = true;
+        }
+      }
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctConstantVolumeFourPipeBeam::AirTerminalSingleDuctConstantVolumeFourPipeBeam(const Model& model)
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl.hpp b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl.hpp
index 09251def1ff..3c142238a31 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeBeam_Impl.hpp
@@ -84,6 +84,11 @@ namespace model {
 
       virtual bool isRemovable() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp
index 1ea227d611a..b44fb2d8c16 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction.cpp
@@ -55,6 +55,7 @@
 #include <utilities/idd/IddEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -559,6 +560,72 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl::componentType() const {
+      bool has_cooling = coolingCoil().is_initialized();
+      bool has_heating = true;  // HC is not optonal
+      if (auto a_ = airLoopHVAC()) {
+        auto compType = a_->componentType();
+        if (compType == ComponentType::Cooling) {
+          has_cooling = true;
+        } else if (compType == ComponentType::Heating) {
+          has_heating = true;
+        } else if (compType == ComponentType::Both) {
+          has_heating = true;
+          has_cooling = true;
+        }
+      }
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctConstantVolumeFourPipeInduction::AirTerminalSingleDuctConstantVolumeFourPipeInduction(const Model& model,
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl.hpp b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl.hpp
index bd1dfb2fdb0..c168ff46540 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeFourPipeInduction_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       unsigned inducedAirInletPort() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeNoReheat.cpp b/src/model/AirTerminalSingleDuctConstantVolumeNoReheat.cpp
index be12010f323..117d46b7adc 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeNoReheat.cpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeNoReheat.cpp
@@ -47,6 +47,7 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_ConstantVolume_NoReheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -281,6 +282,35 @@ namespace model {
       return types;
     }
 
+    ComponentType AirTerminalSingleDuctConstantVolumeNoReheat_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeNoReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeNoReheat_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctConstantVolumeNoReheat_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctConstantVolumeNoReheat::AirTerminalSingleDuctConstantVolumeNoReheat(const Model& model, Schedule& availabilitySchedule)
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeNoReheat_Impl.hpp b/src/model/AirTerminalSingleDuctConstantVolumeNoReheat_Impl.hpp
index 3edfcb37cd9..0273af21866 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeNoReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeNoReheat_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
 
       /** Returns the Schedule referred to by the AvailabilityScheduleName field. **/
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp b/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp
index 824c4ace994..1fd75b95125 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeReheat.cpp
@@ -55,9 +55,9 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_ConstantVolume_Reheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -525,6 +525,52 @@ namespace model {
         setMaximumHotWaterorSteamFlowRate(val.get());
       }
     }
+
+    ComponentType AirTerminalSingleDuctConstantVolumeReheat_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Cooling)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctConstantVolumeReheat_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : reheatCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctConstantVolumeReheat_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctConstantVolumeReheat::AirTerminalSingleDuctConstantVolumeReheat(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/AirTerminalSingleDuctConstantVolumeReheat_Impl.hpp b/src/model/AirTerminalSingleDuctConstantVolumeReheat_Impl.hpp
index c9867080553..f2db978b948 100644
--- a/src/model/AirTerminalSingleDuctConstantVolumeReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctConstantVolumeReheat_Impl.hpp
@@ -82,6 +82,11 @@ namespace model {
 
       virtual ModelObject clone(Model model) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctInletSideMixer.cpp b/src/model/AirTerminalSingleDuctInletSideMixer.cpp
index c6dd2aab5b1..1d402df9ef8 100644
--- a/src/model/AirTerminalSingleDuctInletSideMixer.cpp
+++ b/src/model/AirTerminalSingleDuctInletSideMixer.cpp
@@ -49,6 +49,7 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_InletSideMixer_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -220,6 +221,35 @@ namespace model {
       return result;
     }
 
+    ComponentType AirTerminalSingleDuctInletSideMixer_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctInletSideMixer_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctInletSideMixer_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctInletSideMixer_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctInletSideMixer::AirTerminalSingleDuctInletSideMixer(const Model& model)
diff --git a/src/model/AirTerminalSingleDuctInletSideMixer_Impl.hpp b/src/model/AirTerminalSingleDuctInletSideMixer_Impl.hpp
index c26806fdd73..20ce612eeb4 100644
--- a/src/model/AirTerminalSingleDuctInletSideMixer_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctInletSideMixer_Impl.hpp
@@ -67,6 +67,11 @@ namespace model {
       virtual std::vector<openstudio::IdfObject> remove() override;
       virtual bool isRemovable() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp b/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp
index 4542e26a923..070dd214006 100644
--- a/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp
+++ b/src/model/AirTerminalSingleDuctParallelPIUReheat.cpp
@@ -57,6 +57,7 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_ParallelPIU_Reheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -672,6 +673,51 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctParallelPIUReheat_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Cooling)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctParallelPIUReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctParallelPIUReheat_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : reheatCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctParallelPIUReheat_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctParallelPIUReheat::AirTerminalSingleDuctParallelPIUReheat(const Model& model, Schedule& schedule, HVACComponent& fan,
diff --git a/src/model/AirTerminalSingleDuctParallelPIUReheat_Impl.hpp b/src/model/AirTerminalSingleDuctParallelPIUReheat_Impl.hpp
index aa77a50fb13..d4db2814c17 100644
--- a/src/model/AirTerminalSingleDuctParallelPIUReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctParallelPIUReheat_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctSeriesPIUReheat.cpp b/src/model/AirTerminalSingleDuctSeriesPIUReheat.cpp
index 279e5c4aaba..a54f98a458c 100644
--- a/src/model/AirTerminalSingleDuctSeriesPIUReheat.cpp
+++ b/src/model/AirTerminalSingleDuctSeriesPIUReheat.cpp
@@ -60,8 +60,8 @@
 #include <utilities/idd/OS_AirTerminal_SingleDuct_SeriesPIU_Reheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -562,6 +562,51 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctSeriesPIUReheat_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Cooling)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctSeriesPIUReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctSeriesPIUReheat_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : reheatCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctSeriesPIUReheat_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctSeriesPIUReheat::AirTerminalSingleDuctSeriesPIUReheat(const Model& model, HVACComponent& fan, HVACComponent& reheatCoil)
diff --git a/src/model/AirTerminalSingleDuctSeriesPIUReheat_Impl.hpp b/src/model/AirTerminalSingleDuctSeriesPIUReheat_Impl.hpp
index c04e65cad99..c7607cb7c45 100644
--- a/src/model/AirTerminalSingleDuctSeriesPIUReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctSeriesPIUReheat_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat.cpp b/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat.cpp
index 82eeef20de8..cb0989908d2 100644
--- a/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat.cpp
+++ b/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat.cpp
@@ -47,8 +47,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_AirTerminal_SingleDuct_VAV_HeatAndCool_NoReheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -302,6 +302,35 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctVAVHeatAndCoolNoReheat::AirTerminalSingleDuctVAVHeatAndCoolNoReheat(const Model& model)
diff --git a/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl.hpp b/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl.hpp
index 3245ff2b3f1..a36812d41df 100644
--- a/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctVAVHeatAndCoolNoReheat_Impl.hpp
@@ -67,6 +67,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat.cpp b/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat.cpp
index 9b12705d20f..80b1212d8c9 100644
--- a/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat.cpp
+++ b/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat.cpp
@@ -47,8 +47,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_AirTerminal_SingleDuct_VAV_HeatAndCool_Reheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -425,6 +425,51 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Cooling)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : reheatCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctVAVHeatAndCoolReheat::AirTerminalSingleDuctVAVHeatAndCoolReheat(const Model& model, const HVACComponent& reheatCoil)
diff --git a/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl.hpp b/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl.hpp
index 42c215d5c92..c707347ce06 100644
--- a/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctVAVHeatAndCoolReheat_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctVAVNoReheat.cpp b/src/model/AirTerminalSingleDuctVAVNoReheat.cpp
index 5a889057b90..e2c2676b6c5 100644
--- a/src/model/AirTerminalSingleDuctVAVNoReheat.cpp
+++ b/src/model/AirTerminalSingleDuctVAVNoReheat.cpp
@@ -55,9 +55,9 @@
 #include "Model.hpp"
 #include <utilities/idd/OS_AirTerminal_SingleDuct_VAV_NoReheat_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-//#include <utilities/units/Unit.hpp>
 //#include <utilities/core/Compare.hpp>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -491,6 +491,35 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctVAVNoReheat_Impl::componentType() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->componentType();
+      }
+
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVNoReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVNoReheat_Impl::heatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctVAVNoReheat_Impl::appGHeatingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctVAVNoReheat::AirTerminalSingleDuctVAVNoReheat(const Model& model, Schedule& schedule)
diff --git a/src/model/AirTerminalSingleDuctVAVNoReheat_Impl.hpp b/src/model/AirTerminalSingleDuctVAVNoReheat_Impl.hpp
index 9e3438aacbb..e65085893dd 100644
--- a/src/model/AirTerminalSingleDuctVAVNoReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctVAVNoReheat_Impl.hpp
@@ -77,6 +77,11 @@ namespace model {
 
       virtual bool isRemovable() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/AirTerminalSingleDuctVAVReheat.cpp b/src/model/AirTerminalSingleDuctVAVReheat.cpp
index 785ae349183..ad1bcc1dac8 100644
--- a/src/model/AirTerminalSingleDuctVAVReheat.cpp
+++ b/src/model/AirTerminalSingleDuctVAVReheat.cpp
@@ -52,6 +52,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -701,6 +702,51 @@ namespace model {
       }
     }
 
+    ComponentType AirTerminalSingleDuctVAVReheat_Impl::componentType() const {
+      ComponentType loopType = ComponentType::None;
+      if (auto a_ = airLoopHVAC()) {
+        loopType = a_->componentType();
+      }
+      if ((loopType == ComponentType::Both) or (loopType == ComponentType::Cooling)) {
+        return ComponentType::Both;
+      }
+
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVReheat_Impl::coolingFuelTypes() const {
+      if (auto a_ = airLoopHVAC()) {
+        return a_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> AirTerminalSingleDuctVAVReheat_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : reheatCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> AirTerminalSingleDuctVAVReheat_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : reheatCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      if (auto a_ = airLoopHVAC()) {
+        for (auto ft : a_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   AirTerminalSingleDuctVAVReheat::AirTerminalSingleDuctVAVReheat(const Model& model, Schedule& availabilitySchedule, HVACComponent& coil)
diff --git a/src/model/AirTerminalSingleDuctVAVReheat_Impl.hpp b/src/model/AirTerminalSingleDuctVAVReheat_Impl.hpp
index d4c57851427..61c3696b05c 100644
--- a/src/model/AirTerminalSingleDuctVAVReheat_Impl.hpp
+++ b/src/model/AirTerminalSingleDuctVAVReheat_Impl.hpp
@@ -76,6 +76,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
 
       HVACComponent reheatCoil() const;
diff --git a/src/model/BoilerHotWater.cpp b/src/model/BoilerHotWater.cpp
index 30f9dcc78c6..d338fdef316 100644
--- a/src/model/BoilerHotWater.cpp
+++ b/src/model/BoilerHotWater.cpp
@@ -36,13 +36,13 @@
 #include "Model.hpp"
 #include "Model_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Boiler_HotWater_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -466,6 +466,22 @@ namespace model {
       return setString(OS_Boiler_HotWaterFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType BoilerHotWater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> BoilerHotWater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> BoilerHotWater_Impl::heatingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<AppGFuelType> BoilerHotWater_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(fuelType()))};
+    }
+
   }  // namespace detail
 
   BoilerHotWater::BoilerHotWater(const Model& model) : StraightComponent(BoilerHotWater::iddObjectType(), model) {
diff --git a/src/model/BoilerHotWater_Impl.hpp b/src/model/BoilerHotWater_Impl.hpp
index 5d363f3d321..cc50ab8214f 100644
--- a/src/model/BoilerHotWater_Impl.hpp
+++ b/src/model/BoilerHotWater_Impl.hpp
@@ -77,6 +77,11 @@ namespace model {
 
       virtual ModelObject clone(Model model) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/BoilerSteam.cpp b/src/model/BoilerSteam.cpp
index e8a7c4fe74a..96bd386dd13 100644
--- a/src/model/BoilerSteam.cpp
+++ b/src/model/BoilerSteam.cpp
@@ -31,12 +31,13 @@
 #include "BoilerSteam_Impl.hpp"
 #include "Node.hpp"
 #include "Node_Impl.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Boiler_Steam_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -402,6 +403,22 @@ namespace model {
       return setString(OS_Boiler_SteamFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType BoilerSteam_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> BoilerSteam_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> BoilerSteam_Impl::heatingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<AppGFuelType> BoilerSteam_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(fuelType()))};
+    }
+
   }  // namespace detail
 
   BoilerSteam::BoilerSteam(const Model& model) : StraightComponent(BoilerSteam::iddObjectType(), model) {
diff --git a/src/model/BoilerSteam_Impl.hpp b/src/model/BoilerSteam_Impl.hpp
index 85cd503f4db..d57090dd77e 100644
--- a/src/model/BoilerSteam_Impl.hpp
+++ b/src/model/BoilerSteam_Impl.hpp
@@ -74,6 +74,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CentralHeatPumpSystem.cpp b/src/model/CentralHeatPumpSystem.cpp
index 167ab629b03..a3717d7b788 100644
--- a/src/model/CentralHeatPumpSystem.cpp
+++ b/src/model/CentralHeatPumpSystem.cpp
@@ -47,14 +47,13 @@
 #include "Model.hpp"
 #include "Model_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_CentralHeatPumpSystem_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -329,6 +328,51 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType CentralHeatPumpSystem_Impl::componentType() const {
+      // Note (JM): This really depends on which loop is calling this...
+
+      // This component has a tertiary loop, and is placed on the supply side of TWO loops: Heating and Cooling
+      // If it's the supplyLoop (= cooling), we should probably have a PlantEquipmentOperation::CoolingLoad
+      // If it's the tertiaryLoop (= heating), PlantEquipmentOperation::HeatingLoad
+      // Returning BOTH will place it on a PlantEquipmentOperation::Uncontrolled
+
+      // As a result, this is handled in coolingComponents() and heatingComponents() directly
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> CentralHeatPumpSystem_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = sourcePlantLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> CentralHeatPumpSystem_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = sourcePlantLoop()) {
+        for (auto ft : p_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> CentralHeatPumpSystem_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      result.insert(AppGFuelType::HeatPump);
+      if (auto p_ = sourcePlantLoop()) {
+        for (auto ft : p_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   CentralHeatPumpSystem::CentralHeatPumpSystem(const Model& model) : WaterToWaterComponent(CentralHeatPumpSystem::iddObjectType(), model) {
diff --git a/src/model/CentralHeatPumpSystemModule.cpp b/src/model/CentralHeatPumpSystemModule.cpp
index 6d252212fb5..24289eff6c4 100644
--- a/src/model/CentralHeatPumpSystemModule.cpp
+++ b/src/model/CentralHeatPumpSystemModule.cpp
@@ -187,18 +187,16 @@ namespace model {
     // Convenience function to return parent CentralHeatPumpSystem
     boost::optional<CentralHeatPumpSystem> CentralHeatPumpSystemModule_Impl::centralHeatPumpSystem() const {
 
-      boost::optional<CentralHeatPumpSystem> result;
-
       // loop on all CentralHeatPumpSystems in the model
       for (const CentralHeatPumpSystem& central_hp : this->model().getConcreteModelObjects<CentralHeatPumpSystem>()) {
         // Loop on each CentralHeatPumpSystemModules
         for (const CentralHeatPumpSystemModule& central_hp_module : central_hp.modules()) {
           if (central_hp_module.handle() == this->handle()) {
-            result = central_hp;
+            return central_hp;
           }
         }
       }
-      return result;
+      return boost::none;
     }
 
   }  // namespace detail
diff --git a/src/model/CentralHeatPumpSystem_Impl.hpp b/src/model/CentralHeatPumpSystem_Impl.hpp
index fe5b4dfda44..743c501a044 100644
--- a/src/model/CentralHeatPumpSystem_Impl.hpp
+++ b/src/model/CentralHeatPumpSystem_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -91,6 +92,11 @@ namespace model {
       /* Restricts addToTertiaryNode to a node that is on the supply side of a plant loop (tertiary = Heating Loop) */
       virtual bool addToTertiaryNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ChillerAbsorption.cpp b/src/model/ChillerAbsorption.cpp
index 752e129af4f..e566a119406 100644
--- a/src/model/ChillerAbsorption.cpp
+++ b/src/model/ChillerAbsorption.cpp
@@ -33,10 +33,12 @@
 #include "ChillerAbsorption_Impl.hpp"
 #include "Node.hpp"
 #include "PlantLoop.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Chiller_Absorption_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -538,6 +540,25 @@ namespace model {
       }
     }
 
+    ComponentType ChillerAbsorption_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ChillerAbsorption_Impl::coolingFuelTypes() const {
+      if (auto generatorLoop_ = generatorLoop()) {
+        return generatorLoop_->heatingFuelTypes();  // This is done on purpose. We use heat to produce chilled water here!
+      }
+      return {};
+    }
+
+    std::vector<FuelType> ChillerAbsorption_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ChillerAbsorption_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ChillerAbsorption::ChillerAbsorption(const Model& model) : WaterToWaterComponent(ChillerAbsorption::iddObjectType(), model) {
diff --git a/src/model/ChillerAbsorptionIndirect.cpp b/src/model/ChillerAbsorptionIndirect.cpp
index ff4af1fad2f..7afbdc4b2f9 100644
--- a/src/model/ChillerAbsorptionIndirect.cpp
+++ b/src/model/ChillerAbsorptionIndirect.cpp
@@ -39,10 +39,12 @@
 #include "CurveQuadratic_Impl.hpp"
 #include "Node.hpp"
 #include "PlantLoop.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Chiller_Absorption_Indirect_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -668,6 +670,25 @@ namespace model {
       }
     }
 
+    ComponentType ChillerAbsorptionIndirect_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ChillerAbsorptionIndirect_Impl::coolingFuelTypes() const {
+      if (auto generatorLoop_ = generatorLoop()) {
+        return generatorLoop_->heatingFuelTypes();  // This is done on purpose. We use heat to produce chilled water here!
+      }
+      return {};
+    }
+
+    std::vector<FuelType> ChillerAbsorptionIndirect_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ChillerAbsorptionIndirect_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ChillerAbsorptionIndirect::ChillerAbsorptionIndirect(const Model& model)
diff --git a/src/model/ChillerAbsorptionIndirect_Impl.hpp b/src/model/ChillerAbsorptionIndirect_Impl.hpp
index d2b306bacf1..06396b5529e 100644
--- a/src/model/ChillerAbsorptionIndirect_Impl.hpp
+++ b/src/model/ChillerAbsorptionIndirect_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Curve;
@@ -100,6 +101,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ChillerAbsorption_Impl.hpp b/src/model/ChillerAbsorption_Impl.hpp
index 339239c2cb9..e1c5c7e2cf5 100644
--- a/src/model/ChillerAbsorption_Impl.hpp
+++ b/src/model/ChillerAbsorption_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   namespace detail {
@@ -94,6 +95,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ChillerElectricASHRAE205.cpp b/src/model/ChillerElectricASHRAE205.cpp
index 18a33a96c4b..bab3b407c45 100644
--- a/src/model/ChillerElectricASHRAE205.cpp
+++ b/src/model/ChillerElectricASHRAE205.cpp
@@ -50,9 +50,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Chiller_Electric_ASHRAE205_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -837,6 +836,29 @@ namespace model {
       return mo;
     }
 
+    ComponentType ChillerElectricASHRAE205_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ChillerElectricASHRAE205_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = condenserWaterLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ChillerElectricASHRAE205_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ChillerElectricASHRAE205_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ChillerElectricASHRAE205::ChillerElectricASHRAE205(const ExternalFile& representationFile)
diff --git a/src/model/ChillerElectricASHRAE205_Impl.hpp b/src/model/ChillerElectricASHRAE205_Impl.hpp
index 002ba8d49d5..b258bf2776c 100644
--- a/src/model/ChillerElectricASHRAE205_Impl.hpp
+++ b/src/model/ChillerElectricASHRAE205_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class ExternalFile;
@@ -105,6 +106,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ChillerElectricEIR.cpp b/src/model/ChillerElectricEIR.cpp
index 4a0acf4b48e..52256a1b1fb 100644
--- a/src/model/ChillerElectricEIR.cpp
+++ b/src/model/ChillerElectricEIR.cpp
@@ -42,13 +42,12 @@
 #include "Node_Impl.hpp"
 #include "PlantLoop.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Chiller_Electric_EIR_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -817,6 +816,29 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType ChillerElectricEIR_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ChillerElectricEIR_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = condenserWaterLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ChillerElectricEIR_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ChillerElectricEIR_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ChillerElectricEIR::ChillerElectricEIR(const Model& model, const Curve& CCFofT, const Curve& EItoCORFofT, const Curve& EItoCORFofPLR)
diff --git a/src/model/ChillerElectricEIR_Impl.hpp b/src/model/ChillerElectricEIR_Impl.hpp
index 32c79ca1d1d..763bc667093 100644
--- a/src/model/ChillerElectricEIR_Impl.hpp
+++ b/src/model/ChillerElectricEIR_Impl.hpp
@@ -33,6 +33,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class ChillerElectricEIR;
@@ -100,6 +101,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ChillerElectricReformulatedEIR.cpp b/src/model/ChillerElectricReformulatedEIR.cpp
index 71c42a6bd71..e4a1de3992c 100644
--- a/src/model/ChillerElectricReformulatedEIR.cpp
+++ b/src/model/ChillerElectricReformulatedEIR.cpp
@@ -42,13 +42,13 @@
 #include "Node_Impl.hpp"
 #include "PlantLoop.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Chiller_Electric_ReformulatedEIR_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -719,6 +719,29 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType ChillerElectricReformulatedEIR_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ChillerElectricReformulatedEIR_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = condenserWaterLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ChillerElectricReformulatedEIR_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ChillerElectricReformulatedEIR_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ChillerElectricReformulatedEIR::ChillerElectricReformulatedEIR(const Model& model, const Curve& CCFofT, const Curve& EItoCORFofT,
diff --git a/src/model/ChillerElectricReformulatedEIR_Impl.hpp b/src/model/ChillerElectricReformulatedEIR_Impl.hpp
index efc9fd8b6b9..1050ce56896 100644
--- a/src/model/ChillerElectricReformulatedEIR_Impl.hpp
+++ b/src/model/ChillerElectricReformulatedEIR_Impl.hpp
@@ -33,6 +33,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Curve;
@@ -98,6 +99,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingCooledBeam.cpp b/src/model/CoilCoolingCooledBeam.cpp
index ee82ad01d77..fbb0ecbfc57 100644
--- a/src/model/CoilCoolingCooledBeam.cpp
+++ b/src/model/CoilCoolingCooledBeam.cpp
@@ -40,9 +40,9 @@
 
 #include "Model.hpp"
 #include "Model_Impl.hpp"
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 #include <utilities/idd/IddFactory.hxx>
 
@@ -310,6 +310,25 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType CoilCoolingCooledBeam_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingCooledBeam_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingCooledBeam_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingCooledBeam_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingCooledBeam::CoilCoolingCooledBeam(const Model& model) : StraightComponent(CoilCoolingCooledBeam::iddObjectType(), model) {
diff --git a/src/model/CoilCoolingCooledBeam_Impl.hpp b/src/model/CoilCoolingCooledBeam_Impl.hpp
index dc8c571642e..affcf72b870 100644
--- a/src/model/CoilCoolingCooledBeam_Impl.hpp
+++ b/src/model/CoilCoolingCooledBeam_Impl.hpp
@@ -69,6 +69,11 @@ namespace model {
 
       virtual boost::optional<StraightComponent> containingStraightComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDX.cpp b/src/model/CoilCoolingDX.cpp
index 52d5c3cb46e..533cf5880ce 100644
--- a/src/model/CoilCoolingDX.cpp
+++ b/src/model/CoilCoolingDX.cpp
@@ -60,8 +60,8 @@
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Cooling_DX_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -333,6 +333,22 @@ namespace model {
     //   OS_ASSERT(result);
     // }
 
+    ComponentType CoilCoolingDX_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDX_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDX_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDX_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDX::CoilCoolingDX(const Model& model, const CoilCoolingDXCurveFitPerformance& coilCoolingDXCurveFitPerformance)
diff --git a/src/model/CoilCoolingDXMultiSpeed.cpp b/src/model/CoilCoolingDXMultiSpeed.cpp
index b9f0dd01fab..ada36378d68 100644
--- a/src/model/CoilCoolingDXMultiSpeed.cpp
+++ b/src/model/CoilCoolingDXMultiSpeed.cpp
@@ -47,8 +47,8 @@
 
 #include <utilities/idd/OS_Coil_Cooling_DX_MultiSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -490,6 +490,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType CoilCoolingDXMultiSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXMultiSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXMultiSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXMultiSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXMultiSpeed::CoilCoolingDXMultiSpeed(const Model& model) : StraightComponent(CoilCoolingDXMultiSpeed::iddObjectType(), model) {
diff --git a/src/model/CoilCoolingDXMultiSpeed_Impl.hpp b/src/model/CoilCoolingDXMultiSpeed_Impl.hpp
index 30afa96b5d6..5235e67475c 100644
--- a/src/model/CoilCoolingDXMultiSpeed_Impl.hpp
+++ b/src/model/CoilCoolingDXMultiSpeed_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXSingleSpeed.cpp b/src/model/CoilCoolingDXSingleSpeed.cpp
index 09a633eebe3..171cc5c2417 100644
--- a/src/model/CoilCoolingDXSingleSpeed.cpp
+++ b/src/model/CoilCoolingDXSingleSpeed.cpp
@@ -66,6 +66,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "AirflowNetworkEquivalentDuct.hpp"
 #include "AirflowNetworkEquivalentDuct_Impl.hpp"
 
@@ -879,6 +880,22 @@ namespace model {
       return types;
     }
 
+    ComponentType CoilCoolingDXSingleSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXSingleSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXSingleSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXSingleSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXSingleSpeed::CoilCoolingDXSingleSpeed(const Model& model) : StraightComponent(CoilCoolingDXSingleSpeed::iddObjectType(), model) {
diff --git a/src/model/CoilCoolingDXSingleSpeed_Impl.hpp b/src/model/CoilCoolingDXSingleSpeed_Impl.hpp
index ba113a0b1ec..263a0135b36 100644
--- a/src/model/CoilCoolingDXSingleSpeed_Impl.hpp
+++ b/src/model/CoilCoolingDXSingleSpeed_Impl.hpp
@@ -84,6 +84,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXTwoSpeed.cpp b/src/model/CoilCoolingDXTwoSpeed.cpp
index c8387c96906..1e6dda82c11 100644
--- a/src/model/CoilCoolingDXTwoSpeed.cpp
+++ b/src/model/CoilCoolingDXTwoSpeed.cpp
@@ -54,6 +54,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -796,6 +797,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingDXTwoSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXTwoSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXTwoSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXTwoSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   //This section defines the default values the object gets when created.
diff --git a/src/model/CoilCoolingDXTwoSpeed_Impl.hpp b/src/model/CoilCoolingDXTwoSpeed_Impl.hpp
index 86d923b25d0..38dc8a1fd21 100644
--- a/src/model/CoilCoolingDXTwoSpeed_Impl.hpp
+++ b/src/model/CoilCoolingDXTwoSpeed_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXTwoStageWithHumidityControlMode.cpp b/src/model/CoilCoolingDXTwoStageWithHumidityControlMode.cpp
index b5b6e4b5758..c91310985cd 100644
--- a/src/model/CoilCoolingDXTwoStageWithHumidityControlMode.cpp
+++ b/src/model/CoilCoolingDXTwoStageWithHumidityControlMode.cpp
@@ -56,8 +56,8 @@
 #include "AirflowNetworkEquivalentDuct.hpp"
 #include "AirflowNetworkEquivalentDuct_Impl.hpp"
 #include <utilities/idd/OS_Coil_Cooling_DX_TwoStageWithHumidityControlMode_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include <utilities/idd/IddFactory.hxx>
 
 namespace openstudio {
@@ -491,6 +491,22 @@ namespace model {
       return false;
     }
 
+    ComponentType CoilCoolingDXTwoStageWithHumidityControlMode_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXTwoStageWithHumidityControlMode_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXTwoStageWithHumidityControlMode_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXTwoStageWithHumidityControlMode_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXTwoStageWithHumidityControlMode::CoilCoolingDXTwoStageWithHumidityControlMode(const Model& model)
diff --git a/src/model/CoilCoolingDXTwoStageWithHumidityControlMode_Impl.hpp b/src/model/CoilCoolingDXTwoStageWithHumidityControlMode_Impl.hpp
index b166c913f2d..eef44a7a252 100644
--- a/src/model/CoilCoolingDXTwoStageWithHumidityControlMode_Impl.hpp
+++ b/src/model/CoilCoolingDXTwoStageWithHumidityControlMode_Impl.hpp
@@ -81,6 +81,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXVariableRefrigerantFlow.cpp b/src/model/CoilCoolingDXVariableRefrigerantFlow.cpp
index a96dd5b3da7..343758704c6 100644
--- a/src/model/CoilCoolingDXVariableRefrigerantFlow.cpp
+++ b/src/model/CoilCoolingDXVariableRefrigerantFlow.cpp
@@ -45,8 +45,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_Coil_Cooling_DX_VariableRefrigerantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -282,6 +282,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingDXVariableRefrigerantFlow_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableRefrigerantFlow_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableRefrigerantFlow_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXVariableRefrigerantFlow_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXVariableRefrigerantFlow::CoilCoolingDXVariableRefrigerantFlow(const Model& model)
diff --git a/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl.cpp b/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
index 9f747838954..84cf9e16631 100644
--- a/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
+++ b/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
@@ -46,9 +46,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Cooling_DX_VariableRefrigerantFlow_FluidTemperatureControl_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -241,6 +240,22 @@ namespace model {
       return getAutosizedValue("Design Size Rated Air Flow Rate", "m3/s");
     }
 
+    ComponentType CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl(const Model& model)
diff --git a/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp b/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
index f71c3124599..fe183930389 100644
--- a/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
+++ b/src/model/CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
@@ -68,6 +68,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXVariableRefrigerantFlow_Impl.hpp b/src/model/CoilCoolingDXVariableRefrigerantFlow_Impl.hpp
index f55f0365511..2c7a999ba5c 100644
--- a/src/model/CoilCoolingDXVariableRefrigerantFlow_Impl.hpp
+++ b/src/model/CoilCoolingDXVariableRefrigerantFlow_Impl.hpp
@@ -67,6 +67,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDXVariableSpeed.cpp b/src/model/CoilCoolingDXVariableSpeed.cpp
index ebeca4b752b..cf7b5c671b1 100644
--- a/src/model/CoilCoolingDXVariableSpeed.cpp
+++ b/src/model/CoilCoolingDXVariableSpeed.cpp
@@ -67,8 +67,8 @@
 #include <utilities/idd/OS_Coil_Cooling_DX_VariableSpeed_FieldEnums.hxx>
 
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -680,6 +680,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingDXVariableSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilCoolingDXVariableSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingDXVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingDXVariableSpeed::CoilCoolingDXVariableSpeed(const Model& model) : StraightComponent(CoilCoolingDXVariableSpeed::iddObjectType(), model) {
diff --git a/src/model/CoilCoolingDXVariableSpeed_Impl.hpp b/src/model/CoilCoolingDXVariableSpeed_Impl.hpp
index 1138605186c..4fb2b97d615 100644
--- a/src/model/CoilCoolingDXVariableSpeed_Impl.hpp
+++ b/src/model/CoilCoolingDXVariableSpeed_Impl.hpp
@@ -89,6 +89,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingDX_Impl.hpp b/src/model/CoilCoolingDX_Impl.hpp
index cdba65201fe..4786c343b55 100644
--- a/src/model/CoilCoolingDX_Impl.hpp
+++ b/src/model/CoilCoolingDX_Impl.hpp
@@ -81,6 +81,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingFourPipeBeam.cpp b/src/model/CoilCoolingFourPipeBeam.cpp
index ebac9b9ff40..e4d4dbc0aae 100644
--- a/src/model/CoilCoolingFourPipeBeam.cpp
+++ b/src/model/CoilCoolingFourPipeBeam.cpp
@@ -47,9 +47,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Cooling_FourPipeBeam_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -313,6 +312,25 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType CoilCoolingFourPipeBeam_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingFourPipeBeam_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingFourPipeBeam_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingFourPipeBeam_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   /* Ctor: defaulting Curves like in the FourPipeBeamLargeOffice.idf Example File from E+ */
diff --git a/src/model/CoilCoolingFourPipeBeam_Impl.hpp b/src/model/CoilCoolingFourPipeBeam_Impl.hpp
index 5bd00611f6e..2e3b430076a 100644
--- a/src/model/CoilCoolingFourPipeBeam_Impl.hpp
+++ b/src/model/CoilCoolingFourPipeBeam_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingLowTempRadiantConstFlow.cpp b/src/model/CoilCoolingLowTempRadiantConstFlow.cpp
index d698dc166f1..89291594583 100644
--- a/src/model/CoilCoolingLowTempRadiantConstFlow.cpp
+++ b/src/model/CoilCoolingLowTempRadiantConstFlow.cpp
@@ -49,9 +49,8 @@
 #include <utilities/idd/OS_Coil_Cooling_LowTemperatureRadiant_ConstantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -346,6 +345,25 @@ namespace model {
       return false;
     }
 
+    ComponentType CoilCoolingLowTempRadiantConstFlow_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingLowTempRadiantConstFlow_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingLowTempRadiantConstFlow_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingLowTempRadiantConstFlow_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingLowTempRadiantConstFlow::CoilCoolingLowTempRadiantConstFlow(const Model& model, Schedule& coolingHighWaterTemperatureSchedule,
diff --git a/src/model/CoilCoolingLowTempRadiantConstFlow_Impl.hpp b/src/model/CoilCoolingLowTempRadiantConstFlow_Impl.hpp
index 45bd16341c0..1b31313a83b 100644
--- a/src/model/CoilCoolingLowTempRadiantConstFlow_Impl.hpp
+++ b/src/model/CoilCoolingLowTempRadiantConstFlow_Impl.hpp
@@ -73,6 +73,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingLowTempRadiantVarFlow.cpp b/src/model/CoilCoolingLowTempRadiantVarFlow.cpp
index b1aa0eb66e4..18968e37d94 100644
--- a/src/model/CoilCoolingLowTempRadiantVarFlow.cpp
+++ b/src/model/CoilCoolingLowTempRadiantVarFlow.cpp
@@ -50,9 +50,8 @@
 #include <utilities/idd/OS_Coil_Cooling_LowTemperatureRadiant_VariableFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -394,6 +393,25 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingLowTempRadiantVarFlow_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingLowTempRadiantVarFlow_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingLowTempRadiantVarFlow_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingLowTempRadiantVarFlow_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingLowTempRadiantVarFlow::CoilCoolingLowTempRadiantVarFlow(const Model& model, Schedule& coolingControlTemperatureSchedule)
diff --git a/src/model/CoilCoolingLowTempRadiantVarFlow_Impl.hpp b/src/model/CoilCoolingLowTempRadiantVarFlow_Impl.hpp
index d3bdb1bb087..87d8d9bae36 100644
--- a/src/model/CoilCoolingLowTempRadiantVarFlow_Impl.hpp
+++ b/src/model/CoilCoolingLowTempRadiantVarFlow_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingWater.cpp b/src/model/CoilCoolingWater.cpp
index 82e15524105..1aed7047b2e 100644
--- a/src/model/CoilCoolingWater.cpp
+++ b/src/model/CoilCoolingWater.cpp
@@ -55,6 +55,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -555,6 +556,25 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingWater_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingWater_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingWater_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingWater_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingWater::CoilCoolingWater(const Model& model, Schedule& availableSchedule)
diff --git a/src/model/CoilCoolingWaterPanelRadiant.cpp b/src/model/CoilCoolingWaterPanelRadiant.cpp
index 29c40aaee4b..cebbdc5ae0c 100644
--- a/src/model/CoilCoolingWaterPanelRadiant.cpp
+++ b/src/model/CoilCoolingWaterPanelRadiant.cpp
@@ -46,8 +46,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Cooling_Water_Panel_Radiant_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -333,6 +333,25 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingWaterPanelRadiant_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingWaterPanelRadiant_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> CoilCoolingWaterPanelRadiant_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingWaterPanelRadiant_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingWaterPanelRadiant::CoilCoolingWaterPanelRadiant(const Model& model)
diff --git a/src/model/CoilCoolingWaterPanelRadiant_Impl.hpp b/src/model/CoilCoolingWaterPanelRadiant_Impl.hpp
index 234e865dbeb..72375243fb7 100644
--- a/src/model/CoilCoolingWaterPanelRadiant_Impl.hpp
+++ b/src/model/CoilCoolingWaterPanelRadiant_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
index cec9660525d..2285a083421 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
@@ -47,9 +47,9 @@
 #include <utilities/idd/OS_Coil_Cooling_WaterToAirHeatPump_EquationFit_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -488,6 +488,29 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingWaterToAirHeatPumpEquationFit_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingWaterToAirHeatPumpEquationFit_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> CoilCoolingWaterToAirHeatPumpEquationFit_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingWaterToAirHeatPumpEquationFit_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // Ctors
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
index 1d813b96e06..a74c1d8b088 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.cpp b/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
index c25ef75a4a6..76e94e26adc 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
@@ -51,8 +51,8 @@
 #include <utilities/idd/OS_Coil_Cooling_WaterToAirHeatPump_VariableSpeedEquationFit_FieldEnums.hxx>
 
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -464,6 +464,29 @@ namespace model {
       }
     }
 
+    ComponentType CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit::CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit(const Model& model)
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp b/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
index 528a66c7cb8..7b5da404c5f 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilCoolingWater_Impl.hpp b/src/model/CoilCoolingWater_Impl.hpp
index 96bc60fe804..fe8beffb65b 100644
--- a/src/model/CoilCoolingWater_Impl.hpp
+++ b/src/model/CoilCoolingWater_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual std::vector<ModelObject> children() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
 
       Schedule availabilitySchedule() const;
diff --git a/src/model/CoilHeatingDXMultiSpeed.cpp b/src/model/CoilHeatingDXMultiSpeed.cpp
index 58cdc7eb73a..bd08539be32 100644
--- a/src/model/CoilHeatingDXMultiSpeed.cpp
+++ b/src/model/CoilHeatingDXMultiSpeed.cpp
@@ -49,8 +49,8 @@
 
 #include <utilities/idd/OS_Coil_Heating_DX_MultiSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -545,6 +545,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingDXMultiSpeed_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDXMultiSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDXMultiSpeed_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDXMultiSpeed_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   CoilHeatingDXMultiSpeed::CoilHeatingDXMultiSpeed(const Model& model) : StraightComponent(CoilHeatingDXMultiSpeed::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingDXMultiSpeed_Impl.hpp b/src/model/CoilHeatingDXMultiSpeed_Impl.hpp
index 756845822eb..690a4ca553a 100644
--- a/src/model/CoilHeatingDXMultiSpeed_Impl.hpp
+++ b/src/model/CoilHeatingDXMultiSpeed_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingDXSingleSpeed.cpp b/src/model/CoilHeatingDXSingleSpeed.cpp
index 86478237414..692f5d9f051 100644
--- a/src/model/CoilHeatingDXSingleSpeed.cpp
+++ b/src/model/CoilHeatingDXSingleSpeed.cpp
@@ -64,6 +64,7 @@
 #include <utilities/idd/OS_Coil_Heating_DX_SingleSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -697,6 +698,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingDXSingleSpeed_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDXSingleSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDXSingleSpeed_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDXSingleSpeed_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   CoilHeatingDXSingleSpeed::CoilHeatingDXSingleSpeed(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/CoilHeatingDXSingleSpeed_Impl.hpp b/src/model/CoilHeatingDXSingleSpeed_Impl.hpp
index 00cae1722bb..e3bb8926a13 100644
--- a/src/model/CoilHeatingDXSingleSpeed_Impl.hpp
+++ b/src/model/CoilHeatingDXSingleSpeed_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingDXVariableRefrigerantFlow.cpp b/src/model/CoilHeatingDXVariableRefrigerantFlow.cpp
index 03b0f3ca9c0..69751407226 100644
--- a/src/model/CoilHeatingDXVariableRefrigerantFlow.cpp
+++ b/src/model/CoilHeatingDXVariableRefrigerantFlow.cpp
@@ -43,8 +43,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_Coil_Heating_DX_VariableRefrigerantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -238,6 +238,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingDXVariableRefrigerantFlow_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableRefrigerantFlow_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableRefrigerantFlow_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDXVariableRefrigerantFlow_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   CoilHeatingDXVariableRefrigerantFlow::CoilHeatingDXVariableRefrigerantFlow(const Model& model)
diff --git a/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl.cpp b/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
index 53202c234f8..70ae83037eb 100644
--- a/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
+++ b/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl.cpp
@@ -46,9 +46,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Heating_DX_VariableRefrigerantFlow_FluidTemperatureControl_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -203,6 +202,22 @@ namespace model {
       return getAutosizedValue("Design Size Rated Air Flow Rate", "m3/s");
     }
 
+    ComponentType CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl(const Model& model)
diff --git a/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp b/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
index 6e8e95a1db2..783d29d1ba8 100644
--- a/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
+++ b/src/model/CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp
@@ -68,6 +68,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingDXVariableRefrigerantFlow_Impl.hpp b/src/model/CoilHeatingDXVariableRefrigerantFlow_Impl.hpp
index 3bf007cccf6..dfe4ff94d93 100644
--- a/src/model/CoilHeatingDXVariableRefrigerantFlow_Impl.hpp
+++ b/src/model/CoilHeatingDXVariableRefrigerantFlow_Impl.hpp
@@ -54,12 +54,33 @@ namespace model {
 
       virtual ~CoilHeatingDXVariableRefrigerantFlow_Impl() = default;
 
+      //@}
+      /** @name Virtual Methods */
+      //@{
+
       virtual const std::vector<std::string>& outputVariableNames() const override;
 
       virtual IddObjectType iddObjectType() const override;
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ModelObject clone(Model model) const override;
+
+      virtual std::vector<ModelObject> children() const override;
+
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       Schedule availabilitySchedule() const;
 
       boost::optional<double> ratedTotalHeatingCapacity() const;
@@ -74,6 +95,10 @@ namespace model {
 
       Curve heatingCapacityModifierFunctionofFlowFractionCurve() const;
 
+      //@}
+      /** @name Setters */
+      //@{
+
       bool setAvailabilitySchedule(Schedule& schedule);
 
       bool setRatedTotalHeatingCapacity(boost::optional<double> ratedTotalHeatingCapacity);
@@ -88,18 +113,15 @@ namespace model {
 
       bool setHeatingCapacityModifierFunctionofFlowFractionCurve(const Curve& curve);
 
-      ModelObject clone(Model model) const override;
-
-      std::vector<ModelObject> children() const override;
+      //@}
+      /** @name Other */
+      //@{
 
       boost::optional<double> autosizedRatedTotalHeatingCapacity() const;
 
       boost::optional<double> autosizedRatedAirFlowRate() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
+      //@}
      protected:
      private:
       REGISTER_LOGGER("openstudio.model.CoilHeatingDXVariableRefrigerantFlow");
diff --git a/src/model/CoilHeatingDXVariableSpeed.cpp b/src/model/CoilHeatingDXVariableSpeed.cpp
index 0b1d4643e3a..7806737c6bf 100644
--- a/src/model/CoilHeatingDXVariableSpeed.cpp
+++ b/src/model/CoilHeatingDXVariableSpeed.cpp
@@ -58,8 +58,8 @@
 #include <utilities/idd/OS_Coil_Heating_DX_VariableSpeed_FieldEnums.hxx>
 
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -577,6 +577,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingDXVariableSpeed_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDXVariableSpeed_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDXVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   CoilHeatingDXVariableSpeed::CoilHeatingDXVariableSpeed(const Model& model) : StraightComponent(CoilHeatingDXVariableSpeed::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingDXVariableSpeed_Impl.hpp b/src/model/CoilHeatingDXVariableSpeed_Impl.hpp
index fe7377baf2c..6a65c429b48 100644
--- a/src/model/CoilHeatingDXVariableSpeed_Impl.hpp
+++ b/src/model/CoilHeatingDXVariableSpeed_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingDesuperheater.cpp b/src/model/CoilHeatingDesuperheater.cpp
index 0f3013b40f0..b642ae5086d 100644
--- a/src/model/CoilHeatingDesuperheater.cpp
+++ b/src/model/CoilHeatingDesuperheater.cpp
@@ -50,9 +50,8 @@
 #include <utilities/idd/OS_Coil_Heating_Desuperheater_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -259,6 +258,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType CoilHeatingDesuperheater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingDesuperheater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingDesuperheater_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingDesuperheater_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   CoilHeatingDesuperheater::CoilHeatingDesuperheater(const Model& model) : StraightComponent(CoilHeatingDesuperheater::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingDesuperheater_Impl.hpp b/src/model/CoilHeatingDesuperheater_Impl.hpp
index 4af4a1bb845..df763d4bc16 100644
--- a/src/model/CoilHeatingDesuperheater_Impl.hpp
+++ b/src/model/CoilHeatingDesuperheater_Impl.hpp
@@ -76,6 +76,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingElectric.cpp b/src/model/CoilHeatingElectric.cpp
index bc0c7402f38..764fcd71282 100644
--- a/src/model/CoilHeatingElectric.cpp
+++ b/src/model/CoilHeatingElectric.cpp
@@ -59,6 +59,7 @@
 #include <utilities/idd/OS_Coil_Heating_Electric_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -403,6 +404,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingElectric_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingElectric_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingElectric_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingElectric_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   CoilHeatingElectric::CoilHeatingElectric(const Model& model, Schedule& schedule) : StraightComponent(CoilHeatingElectric::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingElectricMultiStage.cpp b/src/model/CoilHeatingElectricMultiStage.cpp
index 8bedf3def0a..f6ac43b976c 100644
--- a/src/model/CoilHeatingElectricMultiStage.cpp
+++ b/src/model/CoilHeatingElectricMultiStage.cpp
@@ -44,8 +44,8 @@
 
 #include <utilities/idd/OS_Coil_Heating_Electric_MultiStage_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -301,6 +301,22 @@ namespace model {
       return result;
     }
 
+    ComponentType CoilHeatingElectricMultiStage_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingElectricMultiStage_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingElectricMultiStage_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingElectricMultiStage_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   CoilHeatingElectricMultiStage::CoilHeatingElectricMultiStage(const Model& model)
diff --git a/src/model/CoilHeatingElectricMultiStage_Impl.hpp b/src/model/CoilHeatingElectricMultiStage_Impl.hpp
index 39b9f976df1..0b401340984 100644
--- a/src/model/CoilHeatingElectricMultiStage_Impl.hpp
+++ b/src/model/CoilHeatingElectricMultiStage_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingElectric_Impl.hpp b/src/model/CoilHeatingElectric_Impl.hpp
index 094ba2d60f5..63b4d4b58e7 100644
--- a/src/model/CoilHeatingElectric_Impl.hpp
+++ b/src/model/CoilHeatingElectric_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingFourPipeBeam.cpp b/src/model/CoilHeatingFourPipeBeam.cpp
index 7054cdb4688..85cc6904aee 100644
--- a/src/model/CoilHeatingFourPipeBeam.cpp
+++ b/src/model/CoilHeatingFourPipeBeam.cpp
@@ -47,9 +47,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Heating_FourPipeBeam_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -310,6 +309,28 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType CoilHeatingFourPipeBeam_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingFourPipeBeam_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingFourPipeBeam_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingFourPipeBeam_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   /* Ctor: defaulting Curves like in the FourPipeBeamLargeOffice.idf Example File from E+ */
diff --git a/src/model/CoilHeatingFourPipeBeam_Impl.hpp b/src/model/CoilHeatingFourPipeBeam_Impl.hpp
index 997e34b68f7..1aaa3228a92 100644
--- a/src/model/CoilHeatingFourPipeBeam_Impl.hpp
+++ b/src/model/CoilHeatingFourPipeBeam_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingGas.cpp b/src/model/CoilHeatingGas.cpp
index 05787a3e2ae..6cffbadd294 100644
--- a/src/model/CoilHeatingGas.cpp
+++ b/src/model/CoilHeatingGas.cpp
@@ -73,6 +73,7 @@
 #include <utilities/idd/IddFactory.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -545,6 +546,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingGas_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingGas_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingGas_Impl::heatingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingGas_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(fuelType()))};
+    }
+
   }  // namespace detail
 
   // create a new CoilHeatingGas object in the model's workspace
diff --git a/src/model/CoilHeatingGasMultiStage.cpp b/src/model/CoilHeatingGasMultiStage.cpp
index 765469e7efe..e3766938025 100644
--- a/src/model/CoilHeatingGasMultiStage.cpp
+++ b/src/model/CoilHeatingGasMultiStage.cpp
@@ -46,8 +46,8 @@
 
 #include <utilities/idd/OS_Coil_Heating_Gas_MultiStage_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -351,6 +351,22 @@ namespace model {
       return result;
     }
 
+    ComponentType CoilHeatingGasMultiStage_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingGasMultiStage_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingGasMultiStage_Impl::heatingFuelTypes() const {
+      return {FuelType::Gas};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingGasMultiStage_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Fuel};
+    }
+
   }  // namespace detail
 
   CoilHeatingGasMultiStage::CoilHeatingGasMultiStage(const Model& model) : StraightComponent(CoilHeatingGasMultiStage::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingGasMultiStage_Impl.hpp b/src/model/CoilHeatingGasMultiStage_Impl.hpp
index 176ebec23d4..b0c3f32d61f 100644
--- a/src/model/CoilHeatingGasMultiStage_Impl.hpp
+++ b/src/model/CoilHeatingGasMultiStage_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingGas_Impl.hpp b/src/model/CoilHeatingGas_Impl.hpp
index d9a62f1df65..0f40d239b46 100644
--- a/src/model/CoilHeatingGas_Impl.hpp
+++ b/src/model/CoilHeatingGas_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
       virtual boost::optional<HVACComponent> containingHVACComponent() const override;
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters and Setters */
       //@{
diff --git a/src/model/CoilHeatingLowTempRadiantConstFlow.cpp b/src/model/CoilHeatingLowTempRadiantConstFlow.cpp
index b005d867290..55de7ea374f 100644
--- a/src/model/CoilHeatingLowTempRadiantConstFlow.cpp
+++ b/src/model/CoilHeatingLowTempRadiantConstFlow.cpp
@@ -47,9 +47,8 @@
 #include <utilities/idd/OS_Coil_Heating_LowTemperatureRadiant_ConstantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -297,6 +296,28 @@ namespace model {
       return false;
     }
 
+    ComponentType CoilHeatingLowTempRadiantConstFlow_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingLowTempRadiantConstFlow_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingLowTempRadiantConstFlow_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingLowTempRadiantConstFlow_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   CoilHeatingLowTempRadiantConstFlow::CoilHeatingLowTempRadiantConstFlow(const Model& model, Schedule& heatingHighWaterTemperatureSchedule,
diff --git a/src/model/CoilHeatingLowTempRadiantConstFlow_Impl.hpp b/src/model/CoilHeatingLowTempRadiantConstFlow_Impl.hpp
index db0b943d678..0be352a89a9 100644
--- a/src/model/CoilHeatingLowTempRadiantConstFlow_Impl.hpp
+++ b/src/model/CoilHeatingLowTempRadiantConstFlow_Impl.hpp
@@ -72,6 +72,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingLowTempRadiantVarFlow.cpp b/src/model/CoilHeatingLowTempRadiantVarFlow.cpp
index cf5ee210974..659bf5e570a 100644
--- a/src/model/CoilHeatingLowTempRadiantVarFlow.cpp
+++ b/src/model/CoilHeatingLowTempRadiantVarFlow.cpp
@@ -50,9 +50,8 @@
 #include <utilities/idd/OS_Coil_Heating_LowTemperatureRadiant_VariableFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -355,6 +354,28 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingLowTempRadiantVarFlow_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingLowTempRadiantVarFlow_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingLowTempRadiantVarFlow_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingLowTempRadiantVarFlow_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   CoilHeatingLowTempRadiantVarFlow::CoilHeatingLowTempRadiantVarFlow(const Model& model, Schedule& heatingControlTemperature)
diff --git a/src/model/CoilHeatingLowTempRadiantVarFlow_Impl.hpp b/src/model/CoilHeatingLowTempRadiantVarFlow_Impl.hpp
index e03bd0aef90..58953f18f0d 100644
--- a/src/model/CoilHeatingLowTempRadiantVarFlow_Impl.hpp
+++ b/src/model/CoilHeatingLowTempRadiantVarFlow_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingWater.cpp b/src/model/CoilHeatingWater.cpp
index be85a0d692b..07a3a1e1ec7 100644
--- a/src/model/CoilHeatingWater.cpp
+++ b/src/model/CoilHeatingWater.cpp
@@ -76,6 +76,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -631,6 +632,28 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingWater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingWater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingWater_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingWater_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   CoilHeatingWater::CoilHeatingWater(const Model& model, Schedule& availableSchedule)
diff --git a/src/model/CoilHeatingWaterBaseboard.cpp b/src/model/CoilHeatingWaterBaseboard.cpp
index 9614113d73c..3b26df9fbe2 100644
--- a/src/model/CoilHeatingWaterBaseboard.cpp
+++ b/src/model/CoilHeatingWaterBaseboard.cpp
@@ -40,9 +40,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/IddFactory.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -324,6 +323,28 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingWaterBaseboard_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingWaterBaseboard_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingWaterBaseboard_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingWaterBaseboard_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   CoilHeatingWaterBaseboard::CoilHeatingWaterBaseboard(const Model& model) : StraightComponent(CoilHeatingWaterBaseboard::iddObjectType(), model) {
diff --git a/src/model/CoilHeatingWaterBaseboardRadiant.cpp b/src/model/CoilHeatingWaterBaseboardRadiant.cpp
index cbcd895a40e..78d4da6ea5f 100644
--- a/src/model/CoilHeatingWaterBaseboardRadiant.cpp
+++ b/src/model/CoilHeatingWaterBaseboardRadiant.cpp
@@ -42,8 +42,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_Heating_Water_Baseboard_Radiant_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -269,6 +269,28 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingWaterBaseboardRadiant_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingWaterBaseboardRadiant_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingWaterBaseboardRadiant_Impl::heatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingWaterBaseboardRadiant_Impl::appGHeatingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+      return {};
+    }
+
   }  // namespace detail
 
   CoilHeatingWaterBaseboardRadiant::CoilHeatingWaterBaseboardRadiant(const Model& model)
diff --git a/src/model/CoilHeatingWaterBaseboardRadiant_Impl.hpp b/src/model/CoilHeatingWaterBaseboardRadiant_Impl.hpp
index 5792ea504c5..1f65169a84e 100644
--- a/src/model/CoilHeatingWaterBaseboardRadiant_Impl.hpp
+++ b/src/model/CoilHeatingWaterBaseboardRadiant_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingWaterBaseboard_Impl.hpp b/src/model/CoilHeatingWaterBaseboard_Impl.hpp
index 4cb19d9ad0f..8f28f14b5a1 100644
--- a/src/model/CoilHeatingWaterBaseboard_Impl.hpp
+++ b/src/model/CoilHeatingWaterBaseboard_Impl.hpp
@@ -70,6 +70,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
index e05be9943e0..eb78f5d1f8c 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
@@ -43,9 +43,9 @@
 
 #include <utilities/idd/OS_Coil_Heating_WaterToAirHeatPump_EquationFit_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -386,6 +386,36 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingWaterToAirHeatPumpEquationFit_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingWaterToAirHeatPumpEquationFit_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingWaterToAirHeatPumpEquationFit_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingWaterToAirHeatPumpEquationFit_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      result.insert(AppGFuelType::HeatPump);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   // create a new CoilHeatingWaterToAirHeatPumpEquationFit object in the model's workspace
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
index 2803f70cfdc..c8eec6cb50b 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
@@ -74,6 +74,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.cpp b/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
index 4bf16a312df..4dc5b1f77f7 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.cpp
@@ -51,8 +51,8 @@
 #include <utilities/idd/OS_Coil_Heating_WaterToAirHeatPump_VariableSpeedEquationFit_FieldEnums.hxx>
 
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 namespace openstudio {
@@ -418,6 +418,36 @@ namespace model {
       }
     }
 
+    ComponentType CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      result.insert(AppGFuelType::HeatPump);
+      if (auto p_ = plantLoop()) {
+        for (auto ft : p_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit::CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit(const Model& model)
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp b/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
index 68f63404ea8..98eb6d067df 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilHeatingWater_Impl.hpp b/src/model/CoilHeatingWater_Impl.hpp
index 346386a216e..0e1517d490f 100644
--- a/src/model/CoilHeatingWater_Impl.hpp
+++ b/src/model/CoilHeatingWater_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters and Setters */
       //@{
diff --git a/src/model/CoilSystemCoolingDXHeatExchangerAssisted.cpp b/src/model/CoilSystemCoolingDXHeatExchangerAssisted.cpp
index ffe901c0edf..e5074fcca2a 100644
--- a/src/model/CoilSystemCoolingDXHeatExchangerAssisted.cpp
+++ b/src/model/CoilSystemCoolingDXHeatExchangerAssisted.cpp
@@ -57,6 +57,7 @@
 #include <utilities/idd/IddFactory.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -240,6 +241,22 @@ namespace model {
       return false;
     }
 
+    ComponentType CoilSystemCoolingDXHeatExchangerAssisted_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilSystemCoolingDXHeatExchangerAssisted_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoilSystemCoolingDXHeatExchangerAssisted_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilSystemCoolingDXHeatExchangerAssisted_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilSystemCoolingDXHeatExchangerAssisted::CoilSystemCoolingDXHeatExchangerAssisted(const Model& model)
diff --git a/src/model/CoilSystemCoolingDXHeatExchangerAssisted_Impl.hpp b/src/model/CoilSystemCoolingDXHeatExchangerAssisted_Impl.hpp
index ba89f3fbcc2..e661ccd668f 100644
--- a/src/model/CoilSystemCoolingDXHeatExchangerAssisted_Impl.hpp
+++ b/src/model/CoilSystemCoolingDXHeatExchangerAssisted_Impl.hpp
@@ -84,6 +84,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilSystemCoolingWaterHeatExchangerAssisted.cpp b/src/model/CoilSystemCoolingWaterHeatExchangerAssisted.cpp
index 9d2160bd0cf..11da5d8a0a4 100644
--- a/src/model/CoilSystemCoolingWaterHeatExchangerAssisted.cpp
+++ b/src/model/CoilSystemCoolingWaterHeatExchangerAssisted.cpp
@@ -61,6 +61,7 @@
 #include <utilities/idd/OS_CoilSystem_Cooling_Water_HeatExchangerAssisted_FieldEnums.hxx>
 #include <utilities/idd/IddFactory.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -245,6 +246,23 @@ namespace model {
 
       return result;
     }
+
+    ComponentType CoilSystemCoolingWaterHeatExchangerAssisted_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoilSystemCoolingWaterHeatExchangerAssisted_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> CoilSystemCoolingWaterHeatExchangerAssisted_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoilSystemCoolingWaterHeatExchangerAssisted_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoilSystemCoolingWaterHeatExchangerAssisted::CoilSystemCoolingWaterHeatExchangerAssisted(const Model& model)
diff --git a/src/model/CoilSystemCoolingWaterHeatExchangerAssisted_Impl.hpp b/src/model/CoilSystemCoolingWaterHeatExchangerAssisted_Impl.hpp
index ff4c804056c..e2311db0c09 100644
--- a/src/model/CoilSystemCoolingWaterHeatExchangerAssisted_Impl.hpp
+++ b/src/model/CoilSystemCoolingWaterHeatExchangerAssisted_Impl.hpp
@@ -82,6 +82,11 @@ namespace model {
 
       virtual boost::optional<ZoneHVACComponent> containingZoneHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilSystemIntegratedHeatPumpAirSource.cpp b/src/model/CoilSystemIntegratedHeatPumpAirSource.cpp
index 024d8ee85ca..b9e54de18cb 100644
--- a/src/model/CoilSystemIntegratedHeatPumpAirSource.cpp
+++ b/src/model/CoilSystemIntegratedHeatPumpAirSource.cpp
@@ -476,6 +476,64 @@ namespace model {
       return result;
     }
 
+    ComponentType CoilSystemIntegratedHeatPumpAirSource_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> CoilSystemIntegratedHeatPumpAirSource_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+
+      for (auto ft : spaceCoolingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+
+      for (auto ft : scwhCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : scdwhCoolingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : scdwhWaterHeatingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> CoilSystemIntegratedHeatPumpAirSource_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+
+      for (auto ft : spaceHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      // TODO: include dedicatedWaterHeatingCoil? The combined space cooling + water heating ones too?
+      for (auto ft : shdwhHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : shdwhWaterHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> CoilSystemIntegratedHeatPumpAirSource_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+
+      for (auto ft : spaceHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      // TODO: include dedicatedWaterHeatingCoil? The combined space cooling + water heating ones too?
+      for (auto ft : shdwhHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : shdwhWaterHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   CoilSystemIntegratedHeatPumpAirSource::CoilSystemIntegratedHeatPumpAirSource(const Model& model)
diff --git a/src/model/CoilSystemIntegratedHeatPumpAirSource_Impl.hpp b/src/model/CoilSystemIntegratedHeatPumpAirSource_Impl.hpp
index 364b1cbceff..ee76deb1f62 100644
--- a/src/model/CoilSystemIntegratedHeatPumpAirSource_Impl.hpp
+++ b/src/model/CoilSystemIntegratedHeatPumpAirSource_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual boost::optional<HVACComponent> containingHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilUserDefined.cpp b/src/model/CoilUserDefined.cpp
index 24d9dad2394..941e2412d4f 100644
--- a/src/model/CoilUserDefined.cpp
+++ b/src/model/CoilUserDefined.cpp
@@ -44,11 +44,13 @@
 #include "Model_Impl.hpp"
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
-#include <algorithm>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_UserDefined_FieldEnums.hxx>
 
+#include <algorithm>
+
 namespace openstudio {
 namespace model {
 
@@ -499,6 +501,22 @@ namespace model {
       plantOutletTemperatureActuator().setName(newName + "plantOutletTemperatureActuator");
     }
 
+    ComponentType CoilUserDefined_Impl::componentType() const {
+      return ComponentType::Both;  // TODO: Really not sure how to determine this...
+    }
+
+    std::vector<FuelType> CoilUserDefined_Impl::coolingFuelTypes() const {
+      return {};  // TODO: Really not sure how to determine this...
+    }
+
+    std::vector<FuelType> CoilUserDefined_Impl::heatingFuelTypes() const {
+      return {};  // TODO: Really not sure how to determine this...
+    }
+
+    std::vector<AppGFuelType> CoilUserDefined_Impl::appGHeatingFuelTypes() const {
+      return {};  // TODO: Really not sure how to determine this...
+    }
+
   }  // namespace detail
 
   CoilUserDefined::CoilUserDefined(const Model& model) : WaterToAirComponent(CoilUserDefined::iddObjectType(), model) {
diff --git a/src/model/CoilUserDefined_Impl.hpp b/src/model/CoilUserDefined_Impl.hpp
index 18d35bf73ab..425655f3a41 100644
--- a/src/model/CoilUserDefined_Impl.hpp
+++ b/src/model/CoilUserDefined_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual boost::optional<HVACComponent> containingHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPump.cpp b/src/model/CoilWaterHeatingAirToWaterHeatPump.cpp
index d8d390ec63b..0e955b8923e 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPump.cpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPump.cpp
@@ -39,8 +39,8 @@
 #include "CurveQuadratic_Impl.hpp"
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Coil_WaterHeating_AirToWaterHeatPump_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -480,6 +480,22 @@ namespace model {
       }
     }
 
+    ComponentType CoilWaterHeatingAirToWaterHeatPump_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPump_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPump_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilWaterHeatingAirToWaterHeatPump_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};  // TODO: openstudio-standards uses Electric
+    }
+
   }  // namespace detail
 
   CoilWaterHeatingAirToWaterHeatPump::CoilWaterHeatingAirToWaterHeatPump(const Model& model)
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed.cpp b/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed.cpp
index 6b7b634b187..c478c705e60 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed.cpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed.cpp
@@ -50,8 +50,8 @@
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_WaterHeating_AirToWaterHeatPump_VariableSpeed_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -508,6 +508,22 @@ namespace model {
       return getAutosizedValue("TODO", "m3/s");
     }
 
+    ComponentType CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};  // TODO: openstudio-standards uses Electric
+    }
+
   }  // namespace detail
 
   CoilWaterHeatingAirToWaterHeatPumpVariableSpeed::CoilWaterHeatingAirToWaterHeatPumpVariableSpeed(const Model& model)
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl.hpp b/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl.hpp
index 4404fc25dd4..1834d129811 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl.hpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPumpVariableSpeed_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual boost::optional<HVACComponent> containingHVACComponent() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped.cpp b/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped.cpp
index 51658cbc1eb..13a84fd8ad9 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped.cpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped.cpp
@@ -38,8 +38,8 @@
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Coil_WaterHeating_AirToWaterHeatPump_Wrapped_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+// #include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -326,6 +326,22 @@ namespace model {
         OS_Coil_WaterHeating_AirToWaterHeatPump_WrappedFields::PartLoadFractionCorrelationCurveName);
     }
 
+    // ComponentType CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl::componentType() const {
+    //   return ComponentType::Heating;
+    // }
+
+    // std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl::coolingFuelTypes() const {
+    //   return {};
+    // }
+
+    // std::vector<FuelType> CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl::heatingFuelTypes() const {
+    //   return {FuelType::Electricity};
+    // }
+
+    // std::vector<AppGFuelType> CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl::appGHeatingFuelTypes() const {
+    //   return {AppGFuelType::HeatPump};  // TODO: openstudio-standards uses Electric
+    // }
+
   }  // namespace detail
 
   CoilWaterHeatingAirToWaterHeatPumpWrapped::CoilWaterHeatingAirToWaterHeatPumpWrapped(const Model& model)
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl.hpp b/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl.hpp
index d965d2c1ff1..3b013782143 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl.hpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl.hpp
@@ -63,6 +63,12 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      // TODO: This is NOT an HVACComponent
+      // virtual ComponentType componentType() const override;
+      // virtual std::vector<FuelType> coolingFuelTypes() const override;
+      // virtual std::vector<FuelType> heatingFuelTypes() const override;
+      // virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilWaterHeatingAirToWaterHeatPump_Impl.hpp b/src/model/CoilWaterHeatingAirToWaterHeatPump_Impl.hpp
index 082c26a2f72..964532a7824 100644
--- a/src/model/CoilWaterHeatingAirToWaterHeatPump_Impl.hpp
+++ b/src/model/CoilWaterHeatingAirToWaterHeatPump_Impl.hpp
@@ -63,6 +63,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoilWaterHeatingDesuperheater.cpp b/src/model/CoilWaterHeatingDesuperheater.cpp
index fe999c76640..e6eb84af418 100644
--- a/src/model/CoilWaterHeatingDesuperheater.cpp
+++ b/src/model/CoilWaterHeatingDesuperheater.cpp
@@ -52,9 +52,8 @@
 #include <utilities/idd/OS_Coil_WaterHeating_Desuperheater_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -511,6 +510,22 @@ namespace model {
     //   return result;
     // }
 
+    ComponentType CoilWaterHeatingDesuperheater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> CoilWaterHeatingDesuperheater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> CoilWaterHeatingDesuperheater_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> CoilWaterHeatingDesuperheater_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};  // TODO: openstudio-standards uses Electric
+    }
+
   }  // namespace detail
 
   CoilWaterHeatingDesuperheater::CoilWaterHeatingDesuperheater(const Model& model, Schedule& setpointTemperatureSchedule)
diff --git a/src/model/CoilWaterHeatingDesuperheater_Impl.hpp b/src/model/CoilWaterHeatingDesuperheater_Impl.hpp
index 8ffd5a4d823..9a53021a048 100644
--- a/src/model/CoilWaterHeatingDesuperheater_Impl.hpp
+++ b/src/model/CoilWaterHeatingDesuperheater_Impl.hpp
@@ -81,11 +81,10 @@ namespace model {
 
       virtual std::vector<ModelObject> children() const override;
 
-      boost::optional<ModelObject> heatRejectionTarget() const;
-
-      bool addToHeatRejectionTarget(const ModelObject& heatRejectionTarget);
-
-      void removeFromHeatRejectionTarget();
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
 
       //@}
       /** @name Getters */
@@ -187,6 +186,12 @@ namespace model {
       /** @name Other */
       //@{
 
+      boost::optional<ModelObject> heatRejectionTarget() const;
+
+      bool addToHeatRejectionTarget(const ModelObject& heatRejectionTarget);
+
+      void removeFromHeatRejectionTarget();
+
       //@}
      protected:
      private:
diff --git a/src/model/ConnectorMixer.cpp b/src/model/ConnectorMixer.cpp
index 54f60fb54ba..52b4493caef 100644
--- a/src/model/ConnectorMixer.cpp
+++ b/src/model/ConnectorMixer.cpp
@@ -32,10 +32,13 @@
 #include "Node.hpp"
 #include "Model.hpp"
 #include "Model_Impl.hpp"
-#include <utilities/idd/OS_Connector_Mixer_FieldEnums.hxx>
-#include <utilities/idd/IddEnums.hxx>
+
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/OS_Connector_Mixer_FieldEnums.hxx>
+#include <utilities/idd/IddEnums.hxx>
 
 namespace openstudio {
 namespace model {
@@ -96,6 +99,22 @@ namespace model {
       return HVACComponent_Impl::clone(model);
     }
 
+    ComponentType ConnectorMixer_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ConnectorMixer_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ConnectorMixer_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ConnectorMixer_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new Mixer object in the model's workspace
diff --git a/src/model/ConnectorMixer_Impl.hpp b/src/model/ConnectorMixer_Impl.hpp
index b10314b2074..3ddf54d8f0b 100644
--- a/src/model/ConnectorMixer_Impl.hpp
+++ b/src/model/ConnectorMixer_Impl.hpp
@@ -65,6 +65,11 @@ namespace model {
 
       virtual ModelObject clone(Model model) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.ConnectorMixer");
     };
diff --git a/src/model/ConnectorSplitter.cpp b/src/model/ConnectorSplitter.cpp
index 76598295967..f8ba3275270 100644
--- a/src/model/ConnectorSplitter.cpp
+++ b/src/model/ConnectorSplitter.cpp
@@ -34,10 +34,13 @@
 #include "Node.hpp"
 #include "Model.hpp"
 #include "Model_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/core/Compare.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_Connector_Splitter_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Compare.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -147,6 +150,22 @@ namespace model {
       return HVACComponent_Impl::clone(model);
     }
 
+    ComponentType ConnectorSplitter_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ConnectorSplitter_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ConnectorSplitter_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ConnectorSplitter_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ConnectorSplitter::ConnectorSplitter(const Model& model) : Splitter(ConnectorSplitter::iddObjectType(), model) {
diff --git a/src/model/ConnectorSplitter_Impl.hpp b/src/model/ConnectorSplitter_Impl.hpp
index 9506f6ef587..9dc67fe16d4 100644
--- a/src/model/ConnectorSplitter_Impl.hpp
+++ b/src/model/ConnectorSplitter_Impl.hpp
@@ -82,6 +82,11 @@ namespace model {
 
       boost::optional<ModelObject> zoneEquipmentForBranch(int branchIndex);
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.Splitter");
     };
diff --git a/src/model/ControllerWaterCoil.cpp b/src/model/ControllerWaterCoil.cpp
index c386a56a807..3a50231a8f9 100644
--- a/src/model/ControllerWaterCoil.cpp
+++ b/src/model/ControllerWaterCoil.cpp
@@ -31,11 +31,13 @@
 #include "ControllerWaterCoil_Impl.hpp"
 #include "Node.hpp"
 #include "Node_Impl.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Controller_WaterCoil_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -253,6 +255,22 @@ namespace model {
       }
     }
 
+    ComponentType ControllerWaterCoil_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ControllerWaterCoil_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ControllerWaterCoil_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ControllerWaterCoil_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ControllerWaterCoil::ControllerWaterCoil(const Model& model) : HVACComponent(ControllerWaterCoil::iddObjectType(), model) {
diff --git a/src/model/ControllerWaterCoil_Impl.hpp b/src/model/ControllerWaterCoil_Impl.hpp
index 321692c7ebb..3d7549922c6 100644
--- a/src/model/ControllerWaterCoil_Impl.hpp
+++ b/src/model/ControllerWaterCoil_Impl.hpp
@@ -64,6 +64,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoolingTowerSingleSpeed.cpp b/src/model/CoolingTowerSingleSpeed.cpp
index 98f2bc91331..0ba0aebef7a 100644
--- a/src/model/CoolingTowerSingleSpeed.cpp
+++ b/src/model/CoolingTowerSingleSpeed.cpp
@@ -36,12 +36,13 @@
 #include "PlantLoop.hpp"
 #include "PlantLoop_Impl.hpp"
 #include "SizingPlant.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_CoolingTower_SingleSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -978,6 +979,22 @@ namespace model {
       return setString(OS_CoolingTower_SingleSpeedFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType CoolingTowerSingleSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoolingTowerSingleSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoolingTowerSingleSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoolingTowerSingleSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoolingTowerSingleSpeed::CoolingTowerSingleSpeed(const Model& model) : StraightComponent(CoolingTowerSingleSpeed::iddObjectType(), model) {
diff --git a/src/model/CoolingTowerSingleSpeed_Impl.hpp b/src/model/CoolingTowerSingleSpeed_Impl.hpp
index ff8194db516..92d52237fbb 100644
--- a/src/model/CoolingTowerSingleSpeed_Impl.hpp
+++ b/src/model/CoolingTowerSingleSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -73,6 +74,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoolingTowerTwoSpeed.cpp b/src/model/CoolingTowerTwoSpeed.cpp
index 0eca09b4dfa..d83b618dc06 100644
--- a/src/model/CoolingTowerTwoSpeed.cpp
+++ b/src/model/CoolingTowerTwoSpeed.cpp
@@ -38,13 +38,13 @@
 #include "SizingPlant.hpp"
 #include "Node.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_CoolingTower_TwoSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -1219,6 +1219,22 @@ namespace model {
       }
     }
 
+    ComponentType CoolingTowerTwoSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoolingTowerTwoSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoolingTowerTwoSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoolingTowerTwoSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoolingTowerTwoSpeed::CoolingTowerTwoSpeed(const Model& model) : StraightComponent(CoolingTowerTwoSpeed::iddObjectType(), model) {
diff --git a/src/model/CoolingTowerTwoSpeed_Impl.hpp b/src/model/CoolingTowerTwoSpeed_Impl.hpp
index 6aabde1222f..e8dafdb5721 100644
--- a/src/model/CoolingTowerTwoSpeed_Impl.hpp
+++ b/src/model/CoolingTowerTwoSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -75,6 +76,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/CoolingTowerVariableSpeed.cpp b/src/model/CoolingTowerVariableSpeed.cpp
index 12b1f1c9b17..cd49ff61021 100644
--- a/src/model/CoolingTowerVariableSpeed.cpp
+++ b/src/model/CoolingTowerVariableSpeed.cpp
@@ -40,12 +40,13 @@
 #include "CurveCubic_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_CoolingTower_VariableSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -748,6 +749,22 @@ namespace model {
       }
     }
 
+    ComponentType CoolingTowerVariableSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> CoolingTowerVariableSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> CoolingTowerVariableSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> CoolingTowerVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   CoolingTowerVariableSpeed::CoolingTowerVariableSpeed(const Model& model) : StraightComponent(CoolingTowerVariableSpeed::iddObjectType(), model) {
diff --git a/src/model/CoolingTowerVariableSpeed_Impl.hpp b/src/model/CoolingTowerVariableSpeed_Impl.hpp
index aae088b8442..b3e319183af 100644
--- a/src/model/CoolingTowerVariableSpeed_Impl.hpp
+++ b/src/model/CoolingTowerVariableSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class CurveCubic;
@@ -71,6 +72,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/DistrictCooling.cpp b/src/model/DistrictCooling.cpp
index e172cfbe62a..ddd15e61d01 100644
--- a/src/model/DistrictCooling.cpp
+++ b/src/model/DistrictCooling.cpp
@@ -29,14 +29,14 @@
 
 #include "DistrictCooling.hpp"
 #include "DistrictCooling_Impl.hpp"
+#include "Node.hpp"
+#include "Node_Impl.hpp"
 
-#include <utilities/idd/OS_DistrictCooling_FieldEnums.hxx>
-#include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
-#include "Node.hpp"
-#include "Node_Impl.hpp"
+#include <utilities/idd/OS_DistrictCooling_FieldEnums.hxx>
+#include <utilities/idd/IddEnums.hxx>
 
 namespace openstudio {
 namespace model {
@@ -127,6 +127,22 @@ namespace model {
       }
     }
 
+    ComponentType DistrictCooling_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> DistrictCooling_Impl::coolingFuelTypes() const {
+      return {FuelType::DistrictCooling};
+    }
+
+    std::vector<FuelType> DistrictCooling_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> DistrictCooling_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   DistrictCooling::DistrictCooling(const Model& model) : StraightComponent(DistrictCooling::iddObjectType(), model) {
diff --git a/src/model/DistrictCooling_Impl.hpp b/src/model/DistrictCooling_Impl.hpp
index 497b91ad345..3a2f0556794 100644
--- a/src/model/DistrictCooling_Impl.hpp
+++ b/src/model/DistrictCooling_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   namespace detail {
@@ -67,6 +68,15 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -77,10 +87,6 @@ namespace model {
 
       boost::optional<double> autosizedNominalCapacity() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
       //@}
       /** @name Setters */
       //@{
diff --git a/src/model/DistrictHeating.cpp b/src/model/DistrictHeating.cpp
index 5ba6fe7dfca..a4562014416 100644
--- a/src/model/DistrictHeating.cpp
+++ b/src/model/DistrictHeating.cpp
@@ -29,13 +29,14 @@
 
 #include "DistrictHeating.hpp"
 #include "DistrictHeating_Impl.hpp"
+#include "Node.hpp"
+#include "Node_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 #include <utilities/idd/OS_DistrictHeating_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
-#include "Node.hpp"
-#include "Node_Impl.hpp"
 
 namespace openstudio {
 namespace model {
@@ -126,6 +127,22 @@ namespace model {
       }
     }
 
+    ComponentType DistrictHeating_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> DistrictHeating_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> DistrictHeating_Impl::heatingFuelTypes() const {
+      return {FuelType::DistrictHeating};
+    }
+
+    std::vector<AppGFuelType> DistrictHeating_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::District};
+    }
+
   }  // namespace detail
 
   DistrictHeating::DistrictHeating(const Model& model) : StraightComponent(DistrictHeating::iddObjectType(), model) {
diff --git a/src/model/DistrictHeating_Impl.hpp b/src/model/DistrictHeating_Impl.hpp
index 9627b65ff57..c125340c5f7 100644
--- a/src/model/DistrictHeating_Impl.hpp
+++ b/src/model/DistrictHeating_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   namespace detail {
@@ -66,6 +67,14 @@ namespace model {
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
 
       //@}
       /** @name Getters */
@@ -77,10 +86,6 @@ namespace model {
 
       boost::optional<double> autosizedNominalCapacity() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
       //@}
       /** @name Setters */
       //@{
diff --git a/src/model/Duct.cpp b/src/model/Duct.cpp
index 63a848504b0..09ecab2eb18 100644
--- a/src/model/Duct.cpp
+++ b/src/model/Duct.cpp
@@ -33,9 +33,12 @@
 #include "Node_Impl.hpp"
 #include "AirLoopHVACOutdoorAirSystem.hpp"
 #include "AirLoopHVACOutdoorAirSystem_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Duct_FieldEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -83,6 +86,21 @@ namespace model {
       return false;
     }
 
+    ComponentType Duct_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> Duct_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> Duct_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> Duct_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
   }  // namespace detail
 
   Duct::Duct(const Model& model) : StraightComponent(Duct::iddObjectType(), model) {
diff --git a/src/model/Duct_Impl.hpp b/src/model/Duct_Impl.hpp
index 421c8341c68..c65b00b8673 100644
--- a/src/model/Duct_Impl.hpp
+++ b/src/model/Duct_Impl.hpp
@@ -61,14 +61,21 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
-      //@}
-      /** @name Getters */
-      //@{
-
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
 
+      virtual bool addToNode(Node& node) override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       //@}
       /** @name Setters */
       //@{
@@ -77,8 +84,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/EvaporativeCoolerDirectResearchSpecial.cpp b/src/model/EvaporativeCoolerDirectResearchSpecial.cpp
index e29935ca286..17891c94564 100644
--- a/src/model/EvaporativeCoolerDirectResearchSpecial.cpp
+++ b/src/model/EvaporativeCoolerDirectResearchSpecial.cpp
@@ -38,10 +38,13 @@
 #include "Curve.hpp"
 #include "Curve_Impl.hpp"
 #include "Model.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/core/Compare.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_EvaporativeCooler_Direct_ResearchSpecial_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Compare.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -350,6 +353,22 @@ namespace model {
       }
     }
 
+    ComponentType EvaporativeCoolerDirectResearchSpecial_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> EvaporativeCoolerDirectResearchSpecial_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> EvaporativeCoolerDirectResearchSpecial_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> EvaporativeCoolerDirectResearchSpecial_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new EvaporativeCoolerDirectResearchSpecial object in the model's workspace
diff --git a/src/model/EvaporativeCoolerDirectResearchSpecial_Impl.hpp b/src/model/EvaporativeCoolerDirectResearchSpecial_Impl.hpp
index 9a1caa47b41..99f660086d1 100644
--- a/src/model/EvaporativeCoolerDirectResearchSpecial_Impl.hpp
+++ b/src/model/EvaporativeCoolerDirectResearchSpecial_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters and Setters */
       //@{
diff --git a/src/model/EvaporativeCoolerIndirectResearchSpecial.cpp b/src/model/EvaporativeCoolerIndirectResearchSpecial.cpp
index 2d21cd0c9fd..c2f87113dbf 100644
--- a/src/model/EvaporativeCoolerIndirectResearchSpecial.cpp
+++ b/src/model/EvaporativeCoolerIndirectResearchSpecial.cpp
@@ -39,10 +39,12 @@
 #include "Curve_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_EvaporativeCooler_Indirect_ResearchSpecial_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -530,6 +532,22 @@ namespace model {
       }
     }
 
+    ComponentType EvaporativeCoolerIndirectResearchSpecial_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> EvaporativeCoolerIndirectResearchSpecial_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> EvaporativeCoolerIndirectResearchSpecial_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> EvaporativeCoolerIndirectResearchSpecial_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   EvaporativeCoolerIndirectResearchSpecial::EvaporativeCoolerIndirectResearchSpecial(const Model& model)
diff --git a/src/model/EvaporativeCoolerIndirectResearchSpecial_Impl.hpp b/src/model/EvaporativeCoolerIndirectResearchSpecial_Impl.hpp
index d99b434b27d..c21453fa213 100644
--- a/src/model/EvaporativeCoolerIndirectResearchSpecial_Impl.hpp
+++ b/src/model/EvaporativeCoolerIndirectResearchSpecial_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/EvaporativeFluidCoolerSingleSpeed.cpp b/src/model/EvaporativeFluidCoolerSingleSpeed.cpp
index 3c7f6e8ba50..b8c13864dc2 100644
--- a/src/model/EvaporativeFluidCoolerSingleSpeed.cpp
+++ b/src/model/EvaporativeFluidCoolerSingleSpeed.cpp
@@ -47,11 +47,13 @@
 #include "Node_Impl.hpp"
 #include "PortList.hpp"
 #include "PortList_Impl.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_EvaporativeFluidCooler_SingleSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -623,6 +625,22 @@ namespace model {
       }
     }
 
+    ComponentType EvaporativeFluidCoolerSingleSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> EvaporativeFluidCoolerSingleSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> EvaporativeFluidCoolerSingleSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> EvaporativeFluidCoolerSingleSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   EvaporativeFluidCoolerSingleSpeed::EvaporativeFluidCoolerSingleSpeed(const Model& model)
diff --git a/src/model/EvaporativeFluidCoolerSingleSpeed_Impl.hpp b/src/model/EvaporativeFluidCoolerSingleSpeed_Impl.hpp
index 58068e68fd7..b891bdb8c2e 100644
--- a/src/model/EvaporativeFluidCoolerSingleSpeed_Impl.hpp
+++ b/src/model/EvaporativeFluidCoolerSingleSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -73,6 +74,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/EvaporativeFluidCoolerTwoSpeed.cpp b/src/model/EvaporativeFluidCoolerTwoSpeed.cpp
index c0ee395df3b..10e8574f336 100644
--- a/src/model/EvaporativeFluidCoolerTwoSpeed.cpp
+++ b/src/model/EvaporativeFluidCoolerTwoSpeed.cpp
@@ -38,14 +38,13 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_EvaporativeFluidCooler_TwoSpeed_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -830,6 +829,22 @@ namespace model {
       }
     }
 
+    ComponentType EvaporativeFluidCoolerTwoSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> EvaporativeFluidCoolerTwoSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> EvaporativeFluidCoolerTwoSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> EvaporativeFluidCoolerTwoSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   EvaporativeFluidCoolerTwoSpeed::EvaporativeFluidCoolerTwoSpeed(const Model& model)
diff --git a/src/model/EvaporativeFluidCoolerTwoSpeed_Impl.hpp b/src/model/EvaporativeFluidCoolerTwoSpeed_Impl.hpp
index 4537df4e562..0be5b2394fe 100644
--- a/src/model/EvaporativeFluidCoolerTwoSpeed_Impl.hpp
+++ b/src/model/EvaporativeFluidCoolerTwoSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -72,6 +73,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/FanComponentModel.cpp b/src/model/FanComponentModel.cpp
index d30d43ca6da..13cba8d2d90 100644
--- a/src/model/FanComponentModel.cpp
+++ b/src/model/FanComponentModel.cpp
@@ -70,9 +70,8 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Fan_ComponentModel_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -760,6 +759,22 @@ namespace model {
       return getObject<ModelObject>().getModelObjectTarget<Curve>(OS_Fan_ComponentModelFields::NormalizedDimensionlessAirflowCurveNameStallRegion);
     }
 
+    ComponentType FanComponentModel_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanComponentModel_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanComponentModel_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanComponentModel_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   bool FanComponentModel::assignDefaultOptionalCurves() {
diff --git a/src/model/FanComponentModel_Impl.hpp b/src/model/FanComponentModel_Impl.hpp
index 54d1f6c4085..f7834b44396 100644
--- a/src/model/FanComponentModel_Impl.hpp
+++ b/src/model/FanComponentModel_Impl.hpp
@@ -73,6 +73,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/FanConstantVolume.cpp b/src/model/FanConstantVolume.cpp
index 2bee141f878..089f9f21ed2 100644
--- a/src/model/FanConstantVolume.cpp
+++ b/src/model/FanConstantVolume.cpp
@@ -67,6 +67,7 @@
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Compare.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -452,6 +453,22 @@ namespace model {
       return types;
     }
 
+    ComponentType FanConstantVolume_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanConstantVolume_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanConstantVolume_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanConstantVolume_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new FanConstantVolume object in the model's workspace
diff --git a/src/model/FanConstantVolume_Impl.hpp b/src/model/FanConstantVolume_Impl.hpp
index 1709b5be1c4..2f7da7a6d2d 100644
--- a/src/model/FanConstantVolume_Impl.hpp
+++ b/src/model/FanConstantVolume_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters and Setters */
       //@{
diff --git a/src/model/FanOnOff.cpp b/src/model/FanOnOff.cpp
index 4ff30031b37..99a341eafaf 100644
--- a/src/model/FanOnOff.cpp
+++ b/src/model/FanOnOff.cpp
@@ -73,8 +73,8 @@
 #include "AirflowNetworkFan_Impl.hpp"
 #include <utilities/idd/OS_Fan_OnOff_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -504,6 +504,22 @@ namespace model {
       return types;
     }
 
+    ComponentType FanOnOff_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanOnOff_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanOnOff_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanOnOff_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FanOnOff::FanOnOff(const Model& model) : StraightComponent(FanOnOff::iddObjectType(), model) {
diff --git a/src/model/FanOnOff_Impl.hpp b/src/model/FanOnOff_Impl.hpp
index d7f09cefc6c..570726c0f4d 100644
--- a/src/model/FanOnOff_Impl.hpp
+++ b/src/model/FanOnOff_Impl.hpp
@@ -80,6 +80,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters and Setters */
       //@{
diff --git a/src/model/FanSystemModel.cpp b/src/model/FanSystemModel.cpp
index 49f9b76db7d..44630005506 100644
--- a/src/model/FanSystemModel.cpp
+++ b/src/model/FanSystemModel.cpp
@@ -92,8 +92,8 @@
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Fan_SystemModel_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 #include <algorithm>
 
@@ -848,6 +848,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType FanSystemModel_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanSystemModel_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanSystemModel_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanSystemModel_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FanSystemModel::FanSystemModel(const Model& model) : StraightComponent(FanSystemModel::iddObjectType(), model) {
diff --git a/src/model/FanSystemModel_Impl.hpp b/src/model/FanSystemModel_Impl.hpp
index 0cf0177233d..871c5be152a 100644
--- a/src/model/FanSystemModel_Impl.hpp
+++ b/src/model/FanSystemModel_Impl.hpp
@@ -81,6 +81,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/FanVariableVolume.cpp b/src/model/FanVariableVolume.cpp
index 3ef48bf857b..a5d334a4a0d 100644
--- a/src/model/FanVariableVolume.cpp
+++ b/src/model/FanVariableVolume.cpp
@@ -54,6 +54,7 @@
 #include <utilities/idd/OS_Fan_VariableVolume_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -562,6 +563,22 @@ namespace model {
       return types;
     }
 
+    ComponentType FanVariableVolume_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanVariableVolume_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanVariableVolume_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanVariableVolume_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FanVariableVolume::FanVariableVolume(const Model& model, Schedule& schedule) : StraightComponent(FanVariableVolume::iddObjectType(), model) {
diff --git a/src/model/FanVariableVolume_Impl.hpp b/src/model/FanVariableVolume_Impl.hpp
index 73f0707b415..c89b8307cc9 100644
--- a/src/model/FanVariableVolume_Impl.hpp
+++ b/src/model/FanVariableVolume_Impl.hpp
@@ -74,6 +74,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/FanZoneExhaust.cpp b/src/model/FanZoneExhaust.cpp
index 4f6d221a3b1..595c6ace65d 100644
--- a/src/model/FanZoneExhaust.cpp
+++ b/src/model/FanZoneExhaust.cpp
@@ -52,9 +52,8 @@
 #include <utilities/idd/OS_Fan_ZoneExhaust_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -337,6 +336,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType FanZoneExhaust_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> FanZoneExhaust_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> FanZoneExhaust_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FanZoneExhaust_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FanZoneExhaust::FanZoneExhaust(const Model& model) : ZoneHVACComponent(FanZoneExhaust::iddObjectType(), model) {
diff --git a/src/model/FanZoneExhaust_Impl.hpp b/src/model/FanZoneExhaust_Impl.hpp
index cca519b2622..89064edeaf1 100644
--- a/src/model/FanZoneExhaust_Impl.hpp
+++ b/src/model/FanZoneExhaust_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/FluidCoolerSingleSpeed.cpp b/src/model/FluidCoolerSingleSpeed.cpp
index cd169e5d22c..6116170efc0 100644
--- a/src/model/FluidCoolerSingleSpeed.cpp
+++ b/src/model/FluidCoolerSingleSpeed.cpp
@@ -33,13 +33,13 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_FluidCooler_SingleSpeed_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-#include "../utilities/units/Unit.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -313,6 +313,22 @@ namespace model {
       }
     }
 
+    ComponentType FluidCoolerSingleSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> FluidCoolerSingleSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> FluidCoolerSingleSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FluidCoolerSingleSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FluidCoolerSingleSpeed::FluidCoolerSingleSpeed(const Model& model) : StraightComponent(FluidCoolerSingleSpeed::iddObjectType(), model) {
diff --git a/src/model/FluidCoolerSingleSpeed_Impl.hpp b/src/model/FluidCoolerSingleSpeed_Impl.hpp
index 18db1794f57..000c40dcece 100644
--- a/src/model/FluidCoolerSingleSpeed_Impl.hpp
+++ b/src/model/FluidCoolerSingleSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Node;
@@ -63,14 +64,25 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
-      //@}
-      /** @name Getters */
-      //@{
-
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
 
+      virtual bool addToNode(Node& node) override;
+
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       std::string performanceInputMethod() const;
 
       boost::optional<double> designAirFlowRateUfactorTimesAreaValue() const;
@@ -107,10 +119,6 @@ namespace model {
 
       boost::optional<double> autosizedDesignAirFlowRateFanPower() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
       //@}
       /** @name Setters */
       //@{
@@ -149,8 +157,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/FluidCoolerTwoSpeed.cpp b/src/model/FluidCoolerTwoSpeed.cpp
index fffacb1a18d..d418791b6d0 100644
--- a/src/model/FluidCoolerTwoSpeed.cpp
+++ b/src/model/FluidCoolerTwoSpeed.cpp
@@ -33,13 +33,13 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_FluidCooler_TwoSpeed_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-#include "../utilities/units/Unit.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -504,6 +504,22 @@ namespace model {
       }
     }
 
+    ComponentType FluidCoolerTwoSpeed_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> FluidCoolerTwoSpeed_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> FluidCoolerTwoSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> FluidCoolerTwoSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   FluidCoolerTwoSpeed::FluidCoolerTwoSpeed(const Model& model) : StraightComponent(FluidCoolerTwoSpeed::iddObjectType(), model) {
diff --git a/src/model/FluidCoolerTwoSpeed_Impl.hpp b/src/model/FluidCoolerTwoSpeed_Impl.hpp
index e747cc894b0..81572653377 100644
--- a/src/model/FluidCoolerTwoSpeed_Impl.hpp
+++ b/src/model/FluidCoolerTwoSpeed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Node;
@@ -63,14 +64,25 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
-      //@}
-      /** @name Getters */
-      //@{
-
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
 
+      virtual bool addToNode(Node& node) override;
+
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       std::string performanceInputMethod() const;
 
       boost::optional<double> highFanSpeedUfactorTimesAreaValue() const;
@@ -139,10 +151,6 @@ namespace model {
 
       boost::optional<double> autosizedLowFanSpeedFanPower() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
       //@}
       /** @name Setters */
       //@{
@@ -205,8 +213,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger.cpp b/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger.cpp
index ebeee1038c5..ebd0d468da8 100644
--- a/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger.cpp
+++ b/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger.cpp
@@ -56,14 +56,13 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Generator_FuelCell_ExhaustGasToWaterHeatExchanger_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -525,6 +524,22 @@ namespace model {
       return types;
     }
 
+    ComponentType GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity, FuelType::OtherFuel_1};  // TODO: is that right?
+    }
+
+    std::vector<AppGFuelType> GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric, AppGFuelType::Fuel};  // TODO: is that right?
+    }
+
   }  // namespace detail
 
   GeneratorFuelCellExhaustGasToWaterHeatExchanger::GeneratorFuelCellExhaustGasToWaterHeatExchanger(const Model& model,
diff --git a/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl.hpp b/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl.hpp
index f774a337eb3..8a7d2016b3c 100644
--- a/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl.hpp
+++ b/src/model/GeneratorFuelCellExhaustGasToWaterHeatExchanger_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Connection;
@@ -74,19 +75,22 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
-      bool addToNode(Node& node) override;
+      virtual bool addToNode(Node& node) override;
 
-      /*
-     *For OS App-related reasons, so we can drag this object from library onto a plantLoop
-     *This will clone the parent fuelCell (which clones all of his children) and return a reference
-     *to that clone's HX
-     */
+      /** For OS App-related reasons, so we can drag this object from library onto a plantLoop
+        * This will clone the parent fuelCell (which clones all of his children) and return a reference
+        * to that clone's HX */
       virtual ModelObject clone(Model model) const override;
 
       virtual std::vector<IddObjectType> allowableChildTypes() const override;
 
       virtual std::vector<ModelObject> children() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/GeneratorFuelCellStackCooler.cpp b/src/model/GeneratorFuelCellStackCooler.cpp
index 885fbd4a0c7..06bbd4e3559 100644
--- a/src/model/GeneratorFuelCellStackCooler.cpp
+++ b/src/model/GeneratorFuelCellStackCooler.cpp
@@ -40,13 +40,12 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Generator_FuelCell_StackCooler_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -481,6 +480,22 @@ namespace model {
       return false;
     }
 
+    ComponentType GeneratorFuelCellStackCooler_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> GeneratorFuelCellStackCooler_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> GeneratorFuelCellStackCooler_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity, FuelType::OtherFuel_1};  // TODO: is that right?
+    }
+
+    std::vector<AppGFuelType> GeneratorFuelCellStackCooler_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric, AppGFuelType::Fuel};  // TODO: is that right?
+    }
+
   }  // namespace detail
 
   GeneratorFuelCellStackCooler::GeneratorFuelCellStackCooler(const Model& model)
diff --git a/src/model/GeneratorFuelCellStackCooler_Impl.hpp b/src/model/GeneratorFuelCellStackCooler_Impl.hpp
index ae657afe61c..696025d6984 100644
--- a/src/model/GeneratorFuelCellStackCooler_Impl.hpp
+++ b/src/model/GeneratorFuelCellStackCooler_Impl.hpp
@@ -64,6 +64,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/GeneratorMicroTurbineHeatRecovery.cpp b/src/model/GeneratorMicroTurbineHeatRecovery.cpp
index d5f92c32562..0ff8f3daa1e 100644
--- a/src/model/GeneratorMicroTurbineHeatRecovery.cpp
+++ b/src/model/GeneratorMicroTurbineHeatRecovery.cpp
@@ -45,12 +45,13 @@
 // TODO: add the tables class if they get added to OS later?
 //#include "DataTables.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Generator_MicroTurbine_HeatRecovery_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -447,6 +448,23 @@ namespace model {
       std::vector<std::string> types{"Generator Nominal Maximum Power", "Generator Nominal Thermal To Electric Ratio"};
       return types;
     }
+
+    ComponentType GeneratorMicroTurbineHeatRecovery_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> GeneratorMicroTurbineHeatRecovery_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> GeneratorMicroTurbineHeatRecovery_Impl::heatingFuelTypes() const {
+      return {FuelType(generatorMicroTurbine().fuelType())};
+    }
+
+    std::vector<AppGFuelType> GeneratorMicroTurbineHeatRecovery_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(generatorMicroTurbine().fuelType()))};
+    }
+
   }  // namespace detail
 
   // The constructor needs model, and a GeneratorMicroTurbine
diff --git a/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp b/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp
index 17fb546e443..eb72b7199e9 100644
--- a/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp
+++ b/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   // TODO: Check the following class names against object getters and setters.
@@ -69,9 +70,13 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
-      // TODO: I think this should be virtual bool since it's defined in both HVACcomponent and StraightComponent. @Kyle?
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       // DLM: consider reimplementing any other virtual methods of StraightComponent or HVACComponent
 
       //@}
diff --git a/src/model/GroundHeatExchangerHorizontalTrench.cpp b/src/model/GroundHeatExchangerHorizontalTrench.cpp
index e55a69f0562..32d009b7755 100644
--- a/src/model/GroundHeatExchangerHorizontalTrench.cpp
+++ b/src/model/GroundHeatExchangerHorizontalTrench.cpp
@@ -35,10 +35,12 @@
 #include "Node_Impl.hpp"
 #include "SiteGroundTemperatureUndisturbedKusudaAchenbach.hpp"
 #include "SiteGroundTemperatureUndisturbedKusudaAchenbach_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_GroundHeatExchanger_HorizontalTrench_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -280,6 +282,22 @@ namespace model {
       return false;
     }
 
+    ComponentType GroundHeatExchangerHorizontalTrench_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> GroundHeatExchangerHorizontalTrench_Impl::coolingFuelTypes() const {
+      return {FuelType::Geothermal};
+    }
+
+    std::vector<FuelType> GroundHeatExchangerHorizontalTrench_Impl::heatingFuelTypes() const {
+      return {FuelType::Geothermal};
+    }
+
+    std::vector<AppGFuelType> GroundHeatExchangerHorizontalTrench_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Geothermal};
+    }
+
   }  // namespace detail
 
   GroundHeatExchangerHorizontalTrench::GroundHeatExchangerHorizontalTrench(const Model& model)
diff --git a/src/model/GroundHeatExchangerHorizontalTrench_Impl.hpp b/src/model/GroundHeatExchangerHorizontalTrench_Impl.hpp
index bd08f964317..7f6a54532ed 100644
--- a/src/model/GroundHeatExchangerHorizontalTrench_Impl.hpp
+++ b/src/model/GroundHeatExchangerHorizontalTrench_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   namespace detail {
@@ -61,6 +62,17 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual unsigned inletPort() const override;
+
+      virtual unsigned outletPort() const override;
+
+      virtual bool addToNode(Node& node) override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -141,12 +153,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      virtual unsigned inletPort() const override;
-
-      virtual unsigned outletPort() const override;
-
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/GroundHeatExchangerVertical.cpp b/src/model/GroundHeatExchangerVertical.cpp
index 5fffad1e34f..b91af511caf 100644
--- a/src/model/GroundHeatExchangerVertical.cpp
+++ b/src/model/GroundHeatExchangerVertical.cpp
@@ -34,11 +34,12 @@
 #include "Model.hpp"
 #include "Model_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
 #include <utilities/idd/OS_GroundHeatExchanger_Vertical_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -418,6 +419,22 @@ namespace model {
       return result;
     }
 
+    ComponentType GroundHeatExchangerVertical_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> GroundHeatExchangerVertical_Impl::coolingFuelTypes() const {
+      return {FuelType::Geothermal};
+    }
+
+    std::vector<FuelType> GroundHeatExchangerVertical_Impl::heatingFuelTypes() const {
+      return {FuelType::Geothermal};
+    }
+
+    std::vector<AppGFuelType> GroundHeatExchangerVertical_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Geothermal};
+    }
+
   }  // namespace detail
 
   GFunction::GFunction(double lnValue, double gValue) : m_lnValue(lnValue), m_gValue(gValue) {}
diff --git a/src/model/GroundHeatExchangerVertical_Impl.hpp b/src/model/GroundHeatExchangerVertical_Impl.hpp
index 1e496d8031a..fd97e64579b 100644
--- a/src/model/GroundHeatExchangerVertical_Impl.hpp
+++ b/src/model/GroundHeatExchangerVertical_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
   namespace detail {
 
@@ -66,15 +67,12 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
-      bool addToNode(Node& node) override;
-
-      bool addGFunction(double gFunctionLN, double gFunctionGValue);
-
-      void removeGFunction(unsigned groupIndex);
-
-      void removeAllGFunctions();
+      virtual bool addToNode(Node& node) override;
 
-      std::vector<std::pair<double, double>> gFunctions();
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
 
       //@}
       /** @name Getters */
@@ -172,6 +170,14 @@ namespace model {
       /** @name Other */
       //@{
 
+      bool addGFunction(double gFunctionLN, double gFunctionGValue);
+
+      void removeGFunction(unsigned groupIndex);
+
+      void removeAllGFunctions();
+
+      std::vector<std::pair<double, double>> gFunctions();
+
       //@}
      protected:
      private:
diff --git a/src/model/HVACComponent.cpp b/src/model/HVACComponent.cpp
index 058cdcd706d..e469e12ad5d 100644
--- a/src/model/HVACComponent.cpp
+++ b/src/model/HVACComponent.cpp
@@ -49,6 +49,7 @@
 #include "Model_Impl.hpp"
 
 #include "../utilities/core/Assert.hpp"
+// #include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -464,6 +465,22 @@ namespace model {
       return {};
     }
 
+    // ComponentType HVACComponent_Impl::componentType() const {
+    //   return ComponentType::None;
+    // }
+
+    // std::vector<FuelType> HVACComponent_Impl::coolingFuelTypes() const {
+    //   return {};
+    // }
+
+    // std::vector<FuelType> HVACComponent_Impl::heatingFuelTypes() const {
+    //   return {};
+    // }
+
+    // std::vector<AppGFuelType> HVACComponent_Impl::appGHeatingFuelTypes() const {
+    //   return {};
+    // }
+
   }  // namespace detail
 
   HVACComponent::HVACComponent(std::shared_ptr<detail::HVACComponent_Impl> p) : ParentObject(std::move(p)) {}
@@ -532,6 +549,22 @@ namespace model {
     return getImpl<detail::HVACComponent_Impl>()->applySizingValues();
   }
 
+  ComponentType HVACComponent::componentType() const {
+    return getImpl<detail::HVACComponent_Impl>()->componentType();
+  }
+
+  std::vector<FuelType> HVACComponent::coolingFuelTypes() const {
+    return getImpl<detail::HVACComponent_Impl>()->coolingFuelTypes();
+  }
+
+  std::vector<FuelType> HVACComponent::heatingFuelTypes() const {
+    return getImpl<detail::HVACComponent_Impl>()->heatingFuelTypes();
+  }
+
+  std::vector<AppGFuelType> HVACComponent::appGHeatingFuelTypes() const {
+    return getImpl<detail::HVACComponent_Impl>()->appGHeatingFuelTypes();
+  }
+
 }  // namespace model
 
 }  // namespace openstudio
diff --git a/src/model/HVACComponent.hpp b/src/model/HVACComponent.hpp
index c85bf6df664..3737f287148 100644
--- a/src/model/HVACComponent.hpp
+++ b/src/model/HVACComponent.hpp
@@ -35,6 +35,10 @@
 
 namespace openstudio {
 
+class AppGFuelType;
+class ComponentType;
+class FuelType;
+
 namespace model {
 
   class AirLoopHVAC;
@@ -170,6 +174,12 @@ namespace model {
 
     void applySizingValues();
 
+    // This is virtual in the Implementation class
+    ComponentType componentType() const;
+    std::vector<FuelType> coolingFuelTypes() const;
+    std::vector<FuelType> heatingFuelTypes() const;
+    std::vector<AppGFuelType> appGHeatingFuelTypes() const;
+
    protected:
     HVACComponent(IddObjectType type, const Model& model);
 
diff --git a/src/model/HVACComponent_Impl.hpp b/src/model/HVACComponent_Impl.hpp
index 4ded1c00530..4628fa909f1 100644
--- a/src/model/HVACComponent_Impl.hpp
+++ b/src/model/HVACComponent_Impl.hpp
@@ -37,6 +37,10 @@
 
 namespace openstudio {
 
+class AppGFuelType;
+class ComponentType;
+class FuelType;
+
 namespace model {
 
   class Node;
@@ -114,6 +118,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const = 0;
+      virtual std::vector<FuelType> coolingFuelTypes() const = 0;
+      virtual std::vector<FuelType> heatingFuelTypes() const = 0;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const = 0;
+
      protected:
       friend class Model_Impl;
       friend class AirLoopHVAC_Impl;
diff --git a/src/model/HeaderedPumpsConstantSpeed.cpp b/src/model/HeaderedPumpsConstantSpeed.cpp
index 6eba0247595..014221b1489 100644
--- a/src/model/HeaderedPumpsConstantSpeed.cpp
+++ b/src/model/HeaderedPumpsConstantSpeed.cpp
@@ -41,8 +41,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_HeaderedPumps_ConstantSpeed_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -352,6 +352,22 @@ namespace model {
       return setString(OS_HeaderedPumps_ConstantSpeedFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType HeaderedPumpsConstantSpeed_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> HeaderedPumpsConstantSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeaderedPumpsConstantSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeaderedPumpsConstantSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeaderedPumpsConstantSpeed::HeaderedPumpsConstantSpeed(const Model& model) : StraightComponent(HeaderedPumpsConstantSpeed::iddObjectType(), model) {
diff --git a/src/model/HeaderedPumpsConstantSpeed_Impl.hpp b/src/model/HeaderedPumpsConstantSpeed_Impl.hpp
index 7b2a448c89b..4368f1924bf 100644
--- a/src/model/HeaderedPumpsConstantSpeed_Impl.hpp
+++ b/src/model/HeaderedPumpsConstantSpeed_Impl.hpp
@@ -74,6 +74,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeaderedPumpsVariableSpeed.cpp b/src/model/HeaderedPumpsVariableSpeed.cpp
index cecd2b4a2c2..b517bcc0d41 100644
--- a/src/model/HeaderedPumpsVariableSpeed.cpp
+++ b/src/model/HeaderedPumpsVariableSpeed.cpp
@@ -41,8 +41,9 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_HeaderedPumps_VariableSpeed_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -416,6 +417,22 @@ namespace model {
       return setString(OS_HeaderedPumps_VariableSpeedFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType HeaderedPumpsVariableSpeed_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> HeaderedPumpsVariableSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeaderedPumpsVariableSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeaderedPumpsVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeaderedPumpsVariableSpeed::HeaderedPumpsVariableSpeed(const Model& model) : StraightComponent(HeaderedPumpsVariableSpeed::iddObjectType(), model) {
diff --git a/src/model/HeaderedPumpsVariableSpeed_Impl.hpp b/src/model/HeaderedPumpsVariableSpeed_Impl.hpp
index 49b53d26c70..bd1d7bd7b20 100644
--- a/src/model/HeaderedPumpsVariableSpeed_Impl.hpp
+++ b/src/model/HeaderedPumpsVariableSpeed_Impl.hpp
@@ -74,6 +74,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatExchangerAirToAirSensibleAndLatent.cpp b/src/model/HeatExchangerAirToAirSensibleAndLatent.cpp
index 70b8d0c415a..e94c3cb35ab 100644
--- a/src/model/HeatExchangerAirToAirSensibleAndLatent.cpp
+++ b/src/model/HeatExchangerAirToAirSensibleAndLatent.cpp
@@ -41,12 +41,13 @@
 #include "ScheduleTypeRegistry.hpp"
 #include "AirflowNetworkEquivalentDuct.hpp"
 #include "AirflowNetworkEquivalentDuct_Impl.hpp"
-#include <utilities/idd/IddFactory.hxx>
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_HeatExchanger_AirToAir_SensibleAndLatent_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -503,6 +504,22 @@ namespace model {
       }
     }
 
+    ComponentType HeatExchangerAirToAirSensibleAndLatent_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> HeatExchangerAirToAirSensibleAndLatent_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeatExchangerAirToAirSensibleAndLatent_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatExchangerAirToAirSensibleAndLatent_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeatExchangerAirToAirSensibleAndLatent::HeatExchangerAirToAirSensibleAndLatent(const Model& model)
diff --git a/src/model/HeatExchangerAirToAirSensibleAndLatent_Impl.hpp b/src/model/HeatExchangerAirToAirSensibleAndLatent_Impl.hpp
index db884ead0f3..997fd901954 100644
--- a/src/model/HeatExchangerAirToAirSensibleAndLatent_Impl.hpp
+++ b/src/model/HeatExchangerAirToAirSensibleAndLatent_Impl.hpp
@@ -89,6 +89,11 @@ namespace model {
 
       virtual unsigned secondaryAirOutletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatExchangerDesiccantBalancedFlow.cpp b/src/model/HeatExchangerDesiccantBalancedFlow.cpp
index 2fe1b57ce3b..ff120020e18 100644
--- a/src/model/HeatExchangerDesiccantBalancedFlow.cpp
+++ b/src/model/HeatExchangerDesiccantBalancedFlow.cpp
@@ -45,11 +45,12 @@
 #include "HeatExchangerDesiccantBalancedFlowPerformanceDataType1.hpp"
 #include "HeatExchangerDesiccantBalancedFlowPerformanceDataType1_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_HeatExchanger_Desiccant_BalancedFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -263,6 +264,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType HeatExchangerDesiccantBalancedFlow_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> HeatExchangerDesiccantBalancedFlow_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeatExchangerDesiccantBalancedFlow_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatExchangerDesiccantBalancedFlow_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeatExchangerDesiccantBalancedFlow::HeatExchangerDesiccantBalancedFlow(const Model& model)
@@ -340,4 +357,4 @@ namespace model {
   /// @endcond
 
 }  // namespace model
-}  // namespace openstudio
\ No newline at end of file
+}  // namespace openstudio
diff --git a/src/model/HeatExchangerDesiccantBalancedFlow_Impl.hpp b/src/model/HeatExchangerDesiccantBalancedFlow_Impl.hpp
index 35c439134d3..b329c088027 100644
--- a/src/model/HeatExchangerDesiccantBalancedFlow_Impl.hpp
+++ b/src/model/HeatExchangerDesiccantBalancedFlow_Impl.hpp
@@ -86,6 +86,11 @@ namespace model {
 
       virtual unsigned secondaryAirOutletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -135,4 +140,4 @@ namespace model {
 }  // namespace model
 }  // namespace openstudio
 
-#endif  // MODEL_HEATEXCHANGERDESICCANTBALANCEDFLOW_IMPL_HPP
\ No newline at end of file
+#endif  // MODEL_HEATEXCHANGERDESICCANTBALANCEDFLOW_IMPL_HPP
diff --git a/src/model/HeatExchangerFluidToFluid.cpp b/src/model/HeatExchangerFluidToFluid.cpp
index b0d12038b25..856dfeddda6 100644
--- a/src/model/HeatExchangerFluidToFluid.cpp
+++ b/src/model/HeatExchangerFluidToFluid.cpp
@@ -41,15 +41,13 @@
 #include "Model.hpp"
 #include "Model_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_HeatExchanger_FluidToFluid_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -449,6 +447,80 @@ namespace model {
       }
     }
 
+    ComponentType HeatExchangerFluidToFluid_Impl::componentType() const {
+      const std::string controlType = this->controlType();
+
+      if (openstudio::istringEqual(controlType, "HeatingSetpointModulated") || openstudio::istringEqual(controlType, "HeatingSetpointOnOff")) {
+        return ComponentType::Heating;
+
+      } else if (openstudio::istringEqual(controlType, "CoolingSetpointModulated") || openstudio::istringEqual(controlType, "CoolingSetpointOnOff")
+                 || openstudio::istringEqual(controlType, "CoolingDifferentialOnOff")
+                 || openstudio::istringEqual(controlType, "CoolingSetpointOnOffWithComponentOverride")) {
+        return ComponentType::Cooling;
+
+      } else if (openstudio::istringEqual(controlType, "DualDeadbandSetpointModulated")
+                 || openstudio::istringEqual(controlType, "DualDeadbandSetpointOnOff")) {
+        return ComponentType::Both;
+      } else if (openstudio::istringEqual(controlType, "UncontrolledOn")) {
+        // Here we go check what's on the supply side of the secondary plantLoop if there is one
+        // It's going to crash if there isn't a secondary plant Loop anyways
+        // get the Source loop
+        if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+          return p_->componentType();
+        } else {
+          // It isn't connected to a source side (beats the point of the HX)
+          return ComponentType::None;
+        }  // End if has source loop
+
+      } else {
+        // For OperationSchemeModulated and OperationSchemeOnOff
+        LOG(Debug, briefDescription() << "' doesn't have a controlType ('" << controlType
+                                      << "') that allows us to specify whether "
+                                         "it's heating or cooling, setting to ComponentType::BOTH");
+        return ComponentType::Both;
+      }
+    }
+
+    std::vector<FuelType> HeatExchangerFluidToFluid_Impl::coolingFuelTypes() const {
+      const std::string controlType = this->controlType();
+      if (openstudio::istringEqual(controlType, "HeatingSetpointModulated") || openstudio::istringEqual(controlType, "HeatingSetpointOnOff")) {
+        return {};
+      }
+      if (auto p_ = secondaryPlantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+
+      return {};
+    }
+
+    std::vector<FuelType> HeatExchangerFluidToFluid_Impl::heatingFuelTypes() const {
+      const std::string controlType = this->controlType();
+      if (openstudio::istringEqual(controlType, "CoolingSetpointModulated") || openstudio::istringEqual(controlType, "CoolingSetpointOnOff")
+          || openstudio::istringEqual(controlType, "CoolingDifferentialOnOff")
+          || openstudio::istringEqual(controlType, "CoolingSetpointOnOffWithComponentOverride")) {
+        return {};
+      }
+      if (auto p_ = secondaryPlantLoop()) {
+        return p_->heatingFuelTypes();
+      }
+
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatExchangerFluidToFluid_Impl::appGHeatingFuelTypes() const {
+      const std::string controlType = this->controlType();
+      if (openstudio::istringEqual(controlType, "CoolingSetpointModulated") || openstudio::istringEqual(controlType, "CoolingSetpointOnOff")
+          || openstudio::istringEqual(controlType, "CoolingDifferentialOnOff")
+          || openstudio::istringEqual(controlType, "CoolingSetpointOnOffWithComponentOverride")) {
+        return {};
+      }
+      if (auto p_ = secondaryPlantLoop()) {
+        return p_->appGHeatingFuelTypes();
+      }
+
+      return {};
+    }
+
   }  // namespace detail
 
   HeatExchangerFluidToFluid::HeatExchangerFluidToFluid(const Model& model)
diff --git a/src/model/HeatExchangerFluidToFluid_Impl.hpp b/src/model/HeatExchangerFluidToFluid_Impl.hpp
index 5467f466ce8..695bcaff784 100644
--- a/src/model/HeatExchangerFluidToFluid_Impl.hpp
+++ b/src/model/HeatExchangerFluidToFluid_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -78,6 +79,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpAirToWaterFuelFiredCooling.cpp b/src/model/HeatPumpAirToWaterFuelFiredCooling.cpp
index af6071391c5..c56f079a98c 100644
--- a/src/model/HeatPumpAirToWaterFuelFiredCooling.cpp
+++ b/src/model/HeatPumpAirToWaterFuelFiredCooling.cpp
@@ -42,14 +42,13 @@
 #include "HeatPumpAirToWaterFuelFiredHeating.hpp"
 #include "HeatPumpAirToWaterFuelFiredHeating_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_HeatPump_AirToWater_FuelFired_Cooling_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -498,6 +497,22 @@ namespace model {
         OS_HeatPump_AirToWater_FuelFired_CoolingFields::FuelEnergyInputRatioFunctionofPLRCurveName);
     }
 
+    ComponentType HeatPumpAirToWaterFuelFiredCooling_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> HeatPumpAirToWaterFuelFiredCooling_Impl::coolingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<FuelType> HeatPumpAirToWaterFuelFiredCooling_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatPumpAirToWaterFuelFiredCooling_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeatPumpAirToWaterFuelFiredCooling::HeatPumpAirToWaterFuelFiredCooling(const Model& model)
diff --git a/src/model/HeatPumpAirToWaterFuelFiredCooling_Impl.hpp b/src/model/HeatPumpAirToWaterFuelFiredCooling_Impl.hpp
index 5b894114159..7cfbf3483be 100644
--- a/src/model/HeatPumpAirToWaterFuelFiredCooling_Impl.hpp
+++ b/src/model/HeatPumpAirToWaterFuelFiredCooling_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
       // Resets the Companion Heat Pump
       virtual ModelObject clone(Model model) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpAirToWaterFuelFiredHeating.cpp b/src/model/HeatPumpAirToWaterFuelFiredHeating.cpp
index d276c8af169..8cdc135c104 100644
--- a/src/model/HeatPumpAirToWaterFuelFiredHeating.cpp
+++ b/src/model/HeatPumpAirToWaterFuelFiredHeating.cpp
@@ -42,14 +42,13 @@
 #include "HeatPumpAirToWaterFuelFiredCooling.hpp"
 #include "HeatPumpAirToWaterFuelFiredCooling_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_HeatPump_AirToWater_FuelFired_Heating_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -562,6 +561,22 @@ namespace model {
         OS_HeatPump_AirToWater_FuelFired_HeatingFields::FuelEnergyInputRatioFunctionofPLRCurveName);
     }
 
+    ComponentType HeatPumpAirToWaterFuelFiredHeating_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> HeatPumpAirToWaterFuelFiredHeating_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeatPumpAirToWaterFuelFiredHeating_Impl::heatingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<AppGFuelType> HeatPumpAirToWaterFuelFiredHeating_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(fuelType()))};
+    }
+
   }  // namespace detail
 
   HeatPumpAirToWaterFuelFiredHeating::HeatPumpAirToWaterFuelFiredHeating(const Model& model)
diff --git a/src/model/HeatPumpAirToWaterFuelFiredHeating_Impl.hpp b/src/model/HeatPumpAirToWaterFuelFiredHeating_Impl.hpp
index 1099d334c50..7cd067d7d2a 100644
--- a/src/model/HeatPumpAirToWaterFuelFiredHeating_Impl.hpp
+++ b/src/model/HeatPumpAirToWaterFuelFiredHeating_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
       // Resets the Companion Heat Pump
       virtual ModelObject clone(Model model) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpPlantLoopEIRCooling.cpp b/src/model/HeatPumpPlantLoopEIRCooling.cpp
index 63bd51af9ad..ccb3b0cfe75 100644
--- a/src/model/HeatPumpPlantLoopEIRCooling.cpp
+++ b/src/model/HeatPumpPlantLoopEIRCooling.cpp
@@ -39,14 +39,15 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "HeatPumpPlantLoopEIRHeating.hpp"
+#include "HeatPumpPlantLoopEIRHeating_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_HeatPump_PlantLoop_EIR_Cooling_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
-#include "HeatPumpPlantLoopEIRHeating.hpp"
-#include "HeatPumpPlantLoopEIRHeating_Impl.hpp"
 
 namespace openstudio {
 namespace model {
@@ -359,6 +360,22 @@ namespace model {
       }
     }
 
+    ComponentType HeatPumpPlantLoopEIRCooling_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> HeatPumpPlantLoopEIRCooling_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> HeatPumpPlantLoopEIRCooling_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatPumpPlantLoopEIRCooling_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeatPumpPlantLoopEIRCooling::HeatPumpPlantLoopEIRCooling(const Model& model, const Curve& capacityModifierFunctionofTemperatureCurve,
diff --git a/src/model/HeatPumpPlantLoopEIRCooling_Impl.hpp b/src/model/HeatPumpPlantLoopEIRCooling_Impl.hpp
index ba046f2ff1f..8645a3ba49e 100644
--- a/src/model/HeatPumpPlantLoopEIRCooling_Impl.hpp
+++ b/src/model/HeatPumpPlantLoopEIRCooling_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class HeatPumpPlantLoopEIRHeating;
@@ -84,6 +85,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpPlantLoopEIRHeating.cpp b/src/model/HeatPumpPlantLoopEIRHeating.cpp
index e7592471519..a31f4b4bb37 100644
--- a/src/model/HeatPumpPlantLoopEIRHeating.cpp
+++ b/src/model/HeatPumpPlantLoopEIRHeating.cpp
@@ -39,16 +39,18 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "HeatPumpPlantLoopEIRCooling.hpp"
+#include "HeatPumpPlantLoopEIRCooling_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_HeatPump_PlantLoop_EIR_Heating_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
-#include "HeatPumpPlantLoopEIRCooling.hpp"
-#include "HeatPumpPlantLoopEIRCooling_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   namespace detail {
@@ -359,6 +361,22 @@ namespace model {
       }
     }
 
+    ComponentType HeatPumpPlantLoopEIRHeating_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> HeatPumpPlantLoopEIRHeating_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeatPumpPlantLoopEIRHeating_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> HeatPumpPlantLoopEIRHeating_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::HeatPump};
+    }
+
   }  // namespace detail
 
   HeatPumpPlantLoopEIRHeating::HeatPumpPlantLoopEIRHeating(const Model& model, const Curve& capacityModifierFunctionofTemperatureCurve,
diff --git a/src/model/HeatPumpPlantLoopEIRHeating_Impl.hpp b/src/model/HeatPumpPlantLoopEIRHeating_Impl.hpp
index 157d9e0d5b6..eeb9907aec2 100644
--- a/src/model/HeatPumpPlantLoopEIRHeating_Impl.hpp
+++ b/src/model/HeatPumpPlantLoopEIRHeating_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class HeatPumpPlantLoopEIRCooling;
@@ -84,6 +85,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpWaterToWaterEquationFitCooling.cpp b/src/model/HeatPumpWaterToWaterEquationFitCooling.cpp
index b221a41d911..f8b20bda3aa 100644
--- a/src/model/HeatPumpWaterToWaterEquationFitCooling.cpp
+++ b/src/model/HeatPumpWaterToWaterEquationFitCooling.cpp
@@ -33,13 +33,15 @@
 #include "CurveQuadLinear.hpp"
 #include "CurveQuadLinear_Impl.hpp"
 
-#include <utilities/idd/IddEnums.hxx>
-#include <utilities/idd/OS_HeatPump_WaterToWater_EquationFit_Cooling_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 #include "HeatPumpWaterToWaterEquationFitHeating.hpp"
 #include "HeatPumpWaterToWaterEquationFitHeating_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddEnums.hxx>
+#include <utilities/idd/OS_HeatPump_WaterToWater_EquationFit_Cooling_FieldEnums.hxx>
+
 namespace openstudio {
 namespace model {
 
@@ -306,6 +308,29 @@ namespace model {
       }
     }
 
+    ComponentType HeatPumpWaterToWaterEquationFitCooling_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> HeatPumpWaterToWaterEquationFitCooling_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = secondaryPlantLoop()) {
+        for (auto& ft : p_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> HeatPumpWaterToWaterEquationFitCooling_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> HeatPumpWaterToWaterEquationFitCooling_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   HeatPumpWaterToWaterEquationFitCooling::HeatPumpWaterToWaterEquationFitCooling(const Model& model, const CurveQuadLinear& coolingCapacityCurve,
diff --git a/src/model/HeatPumpWaterToWaterEquationFitCooling_Impl.hpp b/src/model/HeatPumpWaterToWaterEquationFitCooling_Impl.hpp
index 546cca24dfa..03ba7d9a049 100644
--- a/src/model/HeatPumpWaterToWaterEquationFitCooling_Impl.hpp
+++ b/src/model/HeatPumpWaterToWaterEquationFitCooling_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class HeatPumpWaterToWaterEquationFitHeating;
@@ -76,6 +77,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HeatPumpWaterToWaterEquationFitHeating.cpp b/src/model/HeatPumpWaterToWaterEquationFitHeating.cpp
index 87447e917f5..9d7afe996ba 100644
--- a/src/model/HeatPumpWaterToWaterEquationFitHeating.cpp
+++ b/src/model/HeatPumpWaterToWaterEquationFitHeating.cpp
@@ -33,13 +33,15 @@
 #include "CurveQuadLinear.hpp"
 #include "CurveQuadLinear_Impl.hpp"
 
-#include <utilities/idd/IddEnums.hxx>
-#include <utilities/idd/OS_HeatPump_WaterToWater_EquationFit_Heating_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 #include "HeatPumpWaterToWaterEquationFitCooling.hpp"
 #include "HeatPumpWaterToWaterEquationFitCooling_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <utilities/idd/IddEnums.hxx>
+#include <utilities/idd/OS_HeatPump_WaterToWater_EquationFit_Heating_FieldEnums.hxx>
+
 namespace openstudio {
 namespace model {
 
@@ -316,6 +318,36 @@ namespace model {
       }
     }
 
+    ComponentType HeatPumpWaterToWaterEquationFitHeating_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> HeatPumpWaterToWaterEquationFitHeating_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HeatPumpWaterToWaterEquationFitHeating_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      result.insert(FuelType::Electricity);
+      if (auto p_ = secondaryPlantLoop()) {
+        for (auto& ft : p_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> HeatPumpWaterToWaterEquationFitHeating_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      result.insert(AppGFuelType::HeatPump);  // TODO: is that right?
+      if (auto p_ = secondaryPlantLoop()) {
+        for (auto& ft : p_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   HeatPumpWaterToWaterEquationFitHeating::HeatPumpWaterToWaterEquationFitHeating(const Model& model, const CurveQuadLinear& heatingCapacityCurve,
diff --git a/src/model/HeatPumpWaterToWaterEquationFitHeating_Impl.hpp b/src/model/HeatPumpWaterToWaterEquationFitHeating_Impl.hpp
index 2e738122279..a76f7fb005a 100644
--- a/src/model/HeatPumpWaterToWaterEquationFitHeating_Impl.hpp
+++ b/src/model/HeatPumpWaterToWaterEquationFitHeating_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class HeatPumpWaterToWaterEquationFitCooling;
@@ -76,6 +77,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HumidifierSteamElectric.cpp b/src/model/HumidifierSteamElectric.cpp
index 816280949c2..12d53d1aeaf 100644
--- a/src/model/HumidifierSteamElectric.cpp
+++ b/src/model/HumidifierSteamElectric.cpp
@@ -35,11 +35,12 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_Humidifier_Steam_Electric_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -258,6 +259,22 @@ namespace model {
       }
     }
 
+    ComponentType HumidifierSteamElectric_Impl::componentType() const {
+      return ComponentType::Heating;  // TODO: is that right?
+    }
+
+    std::vector<FuelType> HumidifierSteamElectric_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HumidifierSteamElectric_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};  // TODO: is that right?
+    }
+
+    std::vector<AppGFuelType> HumidifierSteamElectric_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};  // TODO: is that right?
+    }
+
   }  // namespace detail
 
   HumidifierSteamElectric::HumidifierSteamElectric(const Model& model) : StraightComponent(HumidifierSteamElectric::iddObjectType(), model) {
diff --git a/src/model/HumidifierSteamElectric_Impl.hpp b/src/model/HumidifierSteamElectric_Impl.hpp
index 63648346222..384a0f833a5 100644
--- a/src/model/HumidifierSteamElectric_Impl.hpp
+++ b/src/model/HumidifierSteamElectric_Impl.hpp
@@ -69,6 +69,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/HumidifierSteamGas.cpp b/src/model/HumidifierSteamGas.cpp
index 04c21e3fb6b..7274f4c65ca 100644
--- a/src/model/HumidifierSteamGas.cpp
+++ b/src/model/HumidifierSteamGas.cpp
@@ -37,11 +37,12 @@
 #include "Curve.hpp"
 #include "Curve_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_Humidifier_Steam_Gas_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -343,6 +344,22 @@ namespace model {
       }
     }
 
+    ComponentType HumidifierSteamGas_Impl::componentType() const {
+      return ComponentType::Heating;  // TODO: is that right?
+    }
+
+    std::vector<FuelType> HumidifierSteamGas_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> HumidifierSteamGas_Impl::heatingFuelTypes() const {
+      return {FuelType::Gas};  // TODO: is that right?
+    }
+
+    std::vector<AppGFuelType> HumidifierSteamGas_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Fuel};  // TODO: is that right?
+    }
+
   }  // namespace detail
 
   HumidifierSteamGas::HumidifierSteamGas(const Model& model) : StraightComponent(HumidifierSteamGas::iddObjectType(), model) {
diff --git a/src/model/HumidifierSteamGas_Impl.hpp b/src/model/HumidifierSteamGas_Impl.hpp
index c904cb86f9f..bd828335cb8 100644
--- a/src/model/HumidifierSteamGas_Impl.hpp
+++ b/src/model/HumidifierSteamGas_Impl.hpp
@@ -70,6 +70,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/LoadProfilePlant.cpp b/src/model/LoadProfilePlant.cpp
index 14ec7714345..9aa8c7fd92f 100644
--- a/src/model/LoadProfilePlant.cpp
+++ b/src/model/LoadProfilePlant.cpp
@@ -40,17 +40,16 @@
 #include "Node_Impl.hpp"
 #include "PlantLoop.hpp"
 #include "PlantLoop_Impl.hpp"
-#include "../utilities/time/Time.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+#include "../utilities/time/Time.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_LoadProfile_Plant_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -168,6 +167,22 @@ namespace model {
       return types;
     }
 
+    ComponentType LoadProfilePlant_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> LoadProfilePlant_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> LoadProfilePlant_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> LoadProfilePlant_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   LoadProfilePlant::LoadProfilePlant(const Model& model) : StraightComponent(LoadProfilePlant::iddObjectType(), model) {
diff --git a/src/model/LoadProfilePlant_Impl.hpp b/src/model/LoadProfilePlant_Impl.hpp
index 5d76c9d49d3..23eeb6f6326 100644
--- a/src/model/LoadProfilePlant_Impl.hpp
+++ b/src/model/LoadProfilePlant_Impl.hpp
@@ -72,6 +72,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/Loop.cpp b/src/model/Loop.cpp
index 363933e5659..53e41ffb678 100644
--- a/src/model/Loop.cpp
+++ b/src/model/Loop.cpp
@@ -56,6 +56,7 @@
 #include <utilities/idd/IddEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -383,6 +384,61 @@ namespace model {
     // no autosized fields
     void Loop_Impl::applySizingValues() {}
 
+    ComponentType Loop_Impl::componentType() const {
+      bool has_cooling = false;
+      bool has_heating = false;
+      for (const auto& comp : subsetCastVector<HVACComponent>(supplyComponents())) {
+        auto compType = comp.componentType();
+        if (compType == ComponentType::Cooling) {
+          has_cooling = true;
+        } else if (compType == ComponentType::Heating) {
+          has_heating = true;
+        } else if (compType == ComponentType::Both) {
+          has_cooling = true;
+          has_heating = true;
+        }
+      }
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> Loop_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(supplyComponents())) {
+        for (auto& ft : comp.coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> Loop_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(supplyComponents())) {
+        for (auto& ft : comp.heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> Loop_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(supplyComponents())) {
+        for (auto& ft : comp.appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   Loop::Loop(IddObjectType type, const Model& model) : ParentObject(type, model) {
@@ -491,6 +547,22 @@ namespace model {
     return getImpl<detail::Loop_Impl>()->applySizingValues();
   }
 
+  ComponentType Loop::componentType() const {
+    return getImpl<detail::Loop_Impl>()->componentType();
+  }
+
+  std::vector<FuelType> Loop::coolingFuelTypes() const {
+    return getImpl<detail::Loop_Impl>()->coolingFuelTypes();
+  }
+
+  std::vector<FuelType> Loop::heatingFuelTypes() const {
+    return getImpl<detail::Loop_Impl>()->heatingFuelTypes();
+  }
+
+  std::vector<AppGFuelType> Loop::appGHeatingFuelTypes() const {
+    return getImpl<detail::Loop_Impl>()->appGHeatingFuelTypes();
+  }
+
 }  // namespace model
 
 }  // namespace openstudio
diff --git a/src/model/Loop.hpp b/src/model/Loop.hpp
index de2fe4b9328..1eaa859d112 100644
--- a/src/model/Loop.hpp
+++ b/src/model/Loop.hpp
@@ -34,6 +34,11 @@
 #include "ParentObject.hpp"
 
 namespace openstudio {
+
+class AppGFuelType;
+class ComponentType;
+class FuelType;
+
 namespace model {
 
   namespace detail {
@@ -219,6 +224,11 @@ waterCoolingCoil.addToSplitter( plantLoop.demandSplitter() );
 
     void applySizingValues();
 
+    ComponentType componentType() const;
+    std::vector<FuelType> coolingFuelTypes() const;
+    std::vector<FuelType> heatingFuelTypes() const;
+    std::vector<AppGFuelType> appGHeatingFuelTypes() const;
+
    protected:
     friend class Model;
 
diff --git a/src/model/Loop_Impl.hpp b/src/model/Loop_Impl.hpp
index 0997a686117..a34b96c6d3f 100644
--- a/src/model/Loop_Impl.hpp
+++ b/src/model/Loop_Impl.hpp
@@ -34,6 +34,10 @@
 
 namespace openstudio {
 
+class AppGFuelType;
+class ComponentType;
+class FuelType;
+
 namespace model {
 
   class Node;
@@ -121,6 +125,11 @@ namespace model {
 
       virtual AvailabilityManagerAssignmentList availabilityManagerAssignmentList() const = 0;
 
+      virtual ComponentType componentType() const;
+      virtual std::vector<FuelType> coolingFuelTypes() const;
+      virtual std::vector<FuelType> heatingFuelTypes() const;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const;
+
      private:
       REGISTER_LOGGER("openstudio.model.Loop");
 
diff --git a/src/model/Node.cpp b/src/model/Node.cpp
index 4b8f3663c8e..70e3659ae41 100644
--- a/src/model/Node.cpp
+++ b/src/model/Node.cpp
@@ -49,9 +49,12 @@
 #include "PortList.hpp"
 #include "PortList_Impl.hpp"
 #include "Model.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_Node_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -245,6 +248,22 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType Node_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> Node_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> Node_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> Node_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new Node object in the model's workspace
diff --git a/src/model/Node_Impl.hpp b/src/model/Node_Impl.hpp
index 0687f2abd12..d7190e11e33 100644
--- a/src/model/Node_Impl.hpp
+++ b/src/model/Node_Impl.hpp
@@ -98,6 +98,11 @@ namespace model {
 
       boost::optional<AirflowNetworkDistributionNode> airflowNetworkDistributionNode() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       REGISTER_LOGGER("openstudio.model.Node");
     };
diff --git a/src/model/OutputMeter.cpp b/src/model/OutputMeter.cpp
index 33f93461b34..7eae7879919 100644
--- a/src/model/OutputMeter.cpp
+++ b/src/model/OutputMeter.cpp
@@ -301,6 +301,11 @@ namespace model {
     }
 
     bool OutputMeter_Impl::setFuelType(FuelType type) {
+
+      if ((type == FuelType::Geothermal) || (type == FuelType::Solar)) {
+        LOG_AND_THROW("OutputMeter cannot be instantiated with a FuelType 'Geothermal' nor 'Solar'.");
+      }
+
       auto object = getObject<ModelObject>();
 
       std::string name = OutputMeter::getName(specificEndUse(), endUseType(), type, installLocationType(), specificInstallLocation());
@@ -445,14 +450,14 @@ namespace model {
       if (!result.empty()) {
         result += ":";
       }
-      result += EndUseType(*endUseType).valueName();
+      result += endUseType->valueName();
     }
     if (fuelType) {
       if (!result.empty()) {
         result += ":";
       }
-      result += FuelType(*fuelType)
-                  .valueDescription();  // same as valueName for all, except for FuelType::Gas where it returns "NaturalGas" which is what we want
+      result +=
+        fuelType->valueDescription();  // same as valueName for all, except for FuelType::Gas where it returns "NaturalGas" which is what we want
     }
     if (installLocationType) {
       // there is a weird corner case to handle 'InteriorLights:Electricity:Facility' -> 'InteriorLights:Electricity'
@@ -461,7 +466,7 @@ namespace model {
         if (!result.empty()) {
           result += ":";
         }
-        result += InstallLocationType(*installLocationType).valueName();
+        result += installLocationType->valueName();
       }
     }
     if (specificInstallLocation && !specificInstallLocation->empty()) {
diff --git a/src/model/PipeAdiabatic.cpp b/src/model/PipeAdiabatic.cpp
index 3f32d150b90..843b8764484 100644
--- a/src/model/PipeAdiabatic.cpp
+++ b/src/model/PipeAdiabatic.cpp
@@ -34,10 +34,13 @@
 #include "AirLoopHVAC.hpp"
 #include "AirLoopHVAC_Impl.hpp"
 #include "Model.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/core/Compare.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_Pipe_Adiabatic_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/core/Compare.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 
@@ -84,6 +87,22 @@ namespace model {
       return false;
     }
 
+    ComponentType PipeAdiabatic_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> PipeAdiabatic_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> PipeAdiabatic_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> PipeAdiabatic_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   // create a new PipeAdiabatic object in the model's workspace
diff --git a/src/model/PipeAdiabatic_Impl.hpp b/src/model/PipeAdiabatic_Impl.hpp
index 796a567a45b..417fe8b1296 100644
--- a/src/model/PipeAdiabatic_Impl.hpp
+++ b/src/model/PipeAdiabatic_Impl.hpp
@@ -62,7 +62,12 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
-      bool addToNode(Node& node) override;
+      virtual bool addToNode(Node& node) override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
 
      private:
       REGISTER_LOGGER("openstudio.model.PipeAdiabatic");
diff --git a/src/model/PipeIndoor.cpp b/src/model/PipeIndoor.cpp
index 9fe748a409a..1e6a612c61f 100644
--- a/src/model/PipeIndoor.cpp
+++ b/src/model/PipeIndoor.cpp
@@ -41,13 +41,13 @@
 #include "ThermalZone.hpp"
 #include "ThermalZone_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Pipe_Indoor_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-#include "../utilities/units/Unit.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -208,6 +208,22 @@ namespace model {
       return false;
     }
 
+    ComponentType PipeIndoor_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> PipeIndoor_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> PipeIndoor_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> PipeIndoor_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   PipeIndoor::PipeIndoor(const Model& model) : StraightComponent(PipeIndoor::iddObjectType(), model) {
diff --git a/src/model/PipeIndoor_Impl.hpp b/src/model/PipeIndoor_Impl.hpp
index 20c577bd30e..c61b5391b68 100644
--- a/src/model/PipeIndoor_Impl.hpp
+++ b/src/model/PipeIndoor_Impl.hpp
@@ -67,14 +67,21 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
-      //@}
-      /** @name Getters */
-      //@{
-
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
 
+      virtual bool addToNode(Node& node) override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       boost::optional<Construction> construction() const;
 
       std::string environmentType() const;
@@ -119,8 +126,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/PipeOutdoor.cpp b/src/model/PipeOutdoor.cpp
index ee182ed603a..cde7d3cb0bb 100644
--- a/src/model/PipeOutdoor.cpp
+++ b/src/model/PipeOutdoor.cpp
@@ -35,12 +35,12 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Pipe_Outdoor_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-#include "../utilities/units/Unit.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -147,6 +147,22 @@ namespace model {
       return false;
     }
 
+    ComponentType PipeOutdoor_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> PipeOutdoor_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> PipeOutdoor_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> PipeOutdoor_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   PipeOutdoor::PipeOutdoor(const Model& model) : StraightComponent(PipeOutdoor::iddObjectType(), model) {
diff --git a/src/model/PipeOutdoor_Impl.hpp b/src/model/PipeOutdoor_Impl.hpp
index 585cda56634..b2333e5851c 100644
--- a/src/model/PipeOutdoor_Impl.hpp
+++ b/src/model/PipeOutdoor_Impl.hpp
@@ -64,14 +64,21 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
-      //@}
-      /** @name Getters */
-      //@{
-
       virtual unsigned inletPort() const override;
 
       virtual unsigned outletPort() const override;
 
+      virtual bool addToNode(Node& node) override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       boost::optional<Construction> construction() const;
 
       boost::optional<Node> ambientTemperatureOutdoorAirNode() const;
@@ -100,8 +107,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      bool addToNode(Node& node) override;
-
       //@}
      protected:
      private:
diff --git a/src/model/PlantComponentTemperatureSource.cpp b/src/model/PlantComponentTemperatureSource.cpp
index 8271eff2d0d..c254836a5e3 100644
--- a/src/model/PlantComponentTemperatureSource.cpp
+++ b/src/model/PlantComponentTemperatureSource.cpp
@@ -35,14 +35,13 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_PlantComponent_TemperatureSource_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -194,6 +193,22 @@ namespace model {
       return types;
     }
 
+    ComponentType PlantComponentTemperatureSource_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> PlantComponentTemperatureSource_Impl::coolingFuelTypes() const {
+      return {FuelType::EnergyTransfer};
+    }
+
+    std::vector<FuelType> PlantComponentTemperatureSource_Impl::heatingFuelTypes() const {
+      return {FuelType::EnergyTransfer};
+    }
+
+    std::vector<AppGFuelType> PlantComponentTemperatureSource_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Other};
+    }
+
   }  // namespace detail
 
   PlantComponentTemperatureSource::PlantComponentTemperatureSource(const Model& model)
diff --git a/src/model/PlantComponentTemperatureSource_Impl.hpp b/src/model/PlantComponentTemperatureSource_Impl.hpp
index b90fc744d1d..65ead012427 100644
--- a/src/model/PlantComponentTemperatureSource_Impl.hpp
+++ b/src/model/PlantComponentTemperatureSource_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -71,6 +72,19 @@ namespace model {
 
       // virtual bool addToNode(Node & node) override;
 
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual std::vector<EMSActuatorNames> emsActuatorNames() const override;
+
+      virtual std::vector<std::string> emsInternalVariableNames() const override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -87,14 +101,6 @@ namespace model {
 
       boost::optional<double> autosizedDesignVolumeFlowRate() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
-      virtual std::vector<EMSActuatorNames> emsActuatorNames() const override;
-
-      virtual std::vector<std::string> emsInternalVariableNames() const override;
-
       //@}
       /** @name Setters */
       //@{
diff --git a/src/model/PlantComponentUserDefined.cpp b/src/model/PlantComponentUserDefined.cpp
index 84bf939b8a6..f4ae0d6d3a0 100644
--- a/src/model/PlantComponentUserDefined.cpp
+++ b/src/model/PlantComponentUserDefined.cpp
@@ -46,12 +46,13 @@
 #include "ThermalZone.hpp"
 #include "ThermalZone_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_PlantComponent_UserDefined_FieldEnums.hxx>
 
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -520,6 +521,23 @@ namespace model {
       simProgram.addLine(line);
       return simProgram;
     }
+
+    ComponentType PlantComponentUserDefined_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> PlantComponentUserDefined_Impl::coolingFuelTypes() const {
+      return {FuelType::OtherFuel_1};
+    }
+
+    std::vector<FuelType> PlantComponentUserDefined_Impl::heatingFuelTypes() const {
+      return {FuelType::OtherFuel_1};
+    }
+
+    std::vector<AppGFuelType> PlantComponentUserDefined_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Other};
+    }
+
   }  // namespace detail
 
   PlantComponentUserDefined::PlantComponentUserDefined(const Model& model) : StraightComponent(PlantComponentUserDefined::iddObjectType(), model) {
diff --git a/src/model/PlantComponentUserDefined_Impl.hpp b/src/model/PlantComponentUserDefined_Impl.hpp
index 171c91e4a2d..12f40cfb03f 100644
--- a/src/model/PlantComponentUserDefined_Impl.hpp
+++ b/src/model/PlantComponentUserDefined_Impl.hpp
@@ -39,6 +39,7 @@
 #include "ThermalZone_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   // TODO: Check the following class names against object getters and setters.
@@ -74,6 +75,23 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual unsigned inletPort() const override;
+
+      virtual unsigned outletPort() const override;
+
+      virtual bool addToNode(Node& node) override;
+
+      virtual ModelObject clone(Model model) const override;
+
+      virtual std::vector<IddObjectType> allowableChildTypes() const override;
+
+      virtual std::vector<ModelObject> children() const override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -177,18 +195,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      virtual unsigned inletPort() const override;
-
-      virtual unsigned outletPort() const override;
-
-      bool addToNode(Node& node) override;
-
-      virtual ModelObject clone(Model model) const override;
-
-      virtual std::vector<IddObjectType> allowableChildTypes() const override;
-
-      virtual std::vector<ModelObject> children() const override;
-
       //@}
      protected:
      private:
diff --git a/src/model/PumpConstantSpeed.cpp b/src/model/PumpConstantSpeed.cpp
index 68876db0954..b84a81377e8 100644
--- a/src/model/PumpConstantSpeed.cpp
+++ b/src/model/PumpConstantSpeed.cpp
@@ -45,8 +45,8 @@
 
 #include <utilities/idd/OS_Pump_ConstantSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -533,6 +533,22 @@ namespace model {
       return setString(OS_Pump_ConstantSpeedFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType PumpConstantSpeed_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> PumpConstantSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> PumpConstantSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> PumpConstantSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   PumpConstantSpeed::PumpConstantSpeed(const Model& model) : StraightComponent(PumpConstantSpeed::iddObjectType(), model) {
diff --git a/src/model/PumpConstantSpeed_Impl.hpp b/src/model/PumpConstantSpeed_Impl.hpp
index 033975fa8e6..ba5ddc63101 100644
--- a/src/model/PumpConstantSpeed_Impl.hpp
+++ b/src/model/PumpConstantSpeed_Impl.hpp
@@ -55,12 +55,39 @@ namespace model {
 
       virtual ~PumpConstantSpeed_Impl() = default;
 
+      //@}
+      /** @name Virtual Methods */
+      //@{
+      //
       virtual const std::vector<std::string>& outputVariableNames() const override;
 
       virtual IddObjectType iddObjectType() const override;
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual unsigned inletPort() const override;
+
+      virtual unsigned outletPort() const override;
+
+      virtual bool addToNode(Node& node) override;
+
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual std::vector<EMSActuatorNames> emsActuatorNames() const override;
+
+      virtual std::vector<std::string> emsInternalVariableNames() const override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
+      //@}
+      /** @name Getters */
+      //@{
+
       boost::optional<double> ratedFlowRate() const;
 
       bool isRatedFlowRateAutosized() const;
@@ -99,6 +126,16 @@ namespace model {
 
       std::string endUseSubcategory() const;
 
+      std::string designPowerSizingMethod() const;
+
+      double designElectricPowerPerUnitFlowRate() const;
+
+      double designShaftPowerPerUnitFlowRatePerUnitHead() const;
+
+      //@}
+      /** @name Setters */
+      //@{
+
       bool setRatedFlowRate(boost::optional<double> ratedFlowRate);
 
       void resetRatedFlowRate();
@@ -151,38 +188,23 @@ namespace model {
 
       void resetSkinLossRadiativeFraction();
 
-      virtual unsigned inletPort() const override;
-
-      virtual unsigned outletPort() const override;
-
-      bool addToNode(Node& node) override;
-
-      boost::optional<double> autosizedRatedFlowRate() const;
-
-      boost::optional<double> autosizedRatedPowerConsumption() const;
-
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
-      std::string designPowerSizingMethod() const;
-
       bool setDesignPowerSizingMethod(const std::string& designPowerSizingMethod);
 
-      double designElectricPowerPerUnitFlowRate() const;
-
       bool setDesignElectricPowerPerUnitFlowRate(double designElectricPowerPerUnitFlowRate);
 
-      double designShaftPowerPerUnitFlowRatePerUnitHead() const;
-
       bool setDesignShaftPowerPerUnitFlowRatePerUnitHead(double designShaftPowerPerUnitFlowRatePerUnitHead);
 
-      virtual std::vector<EMSActuatorNames> emsActuatorNames() const override;
+      bool setEndUseSubcategory(const std::string& endUseSubcategory);
 
-      virtual std::vector<std::string> emsInternalVariableNames() const override;
+      //@}
+      /** @name Other */
+      //@{
 
-      bool setEndUseSubcategory(const std::string& endUseSubcategory);
+      boost::optional<double> autosizedRatedFlowRate() const;
+
+      boost::optional<double> autosizedRatedPowerConsumption() const;
 
+      //@}
      protected:
      private:
       REGISTER_LOGGER("openstudio.model.PumpConstantSpeed");
diff --git a/src/model/PumpVariableSpeed.cpp b/src/model/PumpVariableSpeed.cpp
index 4ca442f1e93..8241cd598ca 100644
--- a/src/model/PumpVariableSpeed.cpp
+++ b/src/model/PumpVariableSpeed.cpp
@@ -52,6 +52,7 @@
 #include <utilities/idd/OS_Pump_VariableSpeed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -826,6 +827,22 @@ namespace model {
       return setString(OS_Pump_VariableSpeedFields::EndUseSubcategory, endUseSubcategory);
     }
 
+    ComponentType PumpVariableSpeed_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> PumpVariableSpeed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> PumpVariableSpeed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> PumpVariableSpeed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   PumpVariableSpeed::PumpVariableSpeed(const Model& model) : StraightComponent(PumpVariableSpeed::iddObjectType(), model) {
diff --git a/src/model/PumpVariableSpeed_Impl.hpp b/src/model/PumpVariableSpeed_Impl.hpp
index afb6c04295a..dcca10177d9 100644
--- a/src/model/PumpVariableSpeed_Impl.hpp
+++ b/src/model/PumpVariableSpeed_Impl.hpp
@@ -83,6 +83,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/RefrigerationAirChiller.cpp b/src/model/RefrigerationAirChiller.cpp
index 53953e309f5..3ac2ea6a8ea 100644
--- a/src/model/RefrigerationAirChiller.cpp
+++ b/src/model/RefrigerationAirChiller.cpp
@@ -46,15 +46,13 @@
 #include "ScheduleTypeRegistry.hpp"
 #include "Model.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Refrigeration_AirChiller_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -757,6 +755,22 @@ namespace model {
       }
     }
 
+    ComponentType RefrigerationAirChiller_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> RefrigerationAirChiller_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> RefrigerationAirChiller_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> RefrigerationAirChiller_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   RefrigerationAirChiller::RefrigerationAirChiller(const Model& model, Schedule& defrostSchedule)
diff --git a/src/model/RefrigerationAirChiller_Impl.hpp b/src/model/RefrigerationAirChiller_Impl.hpp
index 1907f7928a7..b2ca66dd296 100644
--- a/src/model/RefrigerationAirChiller_Impl.hpp
+++ b/src/model/RefrigerationAirChiller_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual boost::optional<ThermalZone> thermalZone() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/RefrigerationCompressorRack.cpp b/src/model/RefrigerationCompressorRack.cpp
index eb746b80228..78c4b1c4e16 100644
--- a/src/model/RefrigerationCompressorRack.cpp
+++ b/src/model/RefrigerationCompressorRack.cpp
@@ -53,15 +53,13 @@
 #include "ScheduleTypeRegistry.hpp"
 #include "Node.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Refrigeration_CompressorRack_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -684,6 +682,22 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType RefrigerationCompressorRack_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> RefrigerationCompressorRack_Impl::coolingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<FuelType> RefrigerationCompressorRack_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> RefrigerationCompressorRack_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   RefrigerationCompressorRack::RefrigerationCompressorRack(const Model& model)
diff --git a/src/model/RefrigerationCompressorRack_Impl.hpp b/src/model/RefrigerationCompressorRack_Impl.hpp
index 66d7b04452e..60c5bceecdb 100644
--- a/src/model/RefrigerationCompressorRack_Impl.hpp
+++ b/src/model/RefrigerationCompressorRack_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual std::vector<IdfObject> remove() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/RefrigerationCondenserWaterCooled.cpp b/src/model/RefrigerationCondenserWaterCooled.cpp
index 7d8ecaf1b3f..8d232e92c94 100644
--- a/src/model/RefrigerationCondenserWaterCooled.cpp
+++ b/src/model/RefrigerationCondenserWaterCooled.cpp
@@ -39,15 +39,13 @@
 #include "ScheduleTypeRegistry.hpp"
 #include "Node.hpp"
 
-#include <utilities/idd/IddFactory.hxx>
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
+#include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_Refrigeration_Condenser_WaterCooled_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -409,6 +407,25 @@ namespace model {
       return system;
     }
 
+    ComponentType RefrigerationCondenserWaterCooled_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> RefrigerationCondenserWaterCooled_Impl::coolingFuelTypes() const {
+      if (auto p_ = plantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> RefrigerationCondenserWaterCooled_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> RefrigerationCondenserWaterCooled_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   RefrigerationCondenserWaterCooled::RefrigerationCondenserWaterCooled(const Model& model)
diff --git a/src/model/RefrigerationCondenserWaterCooled_Impl.hpp b/src/model/RefrigerationCondenserWaterCooled_Impl.hpp
index 9c22da3f071..4abc3db8d2e 100644
--- a/src/model/RefrigerationCondenserWaterCooled_Impl.hpp
+++ b/src/model/RefrigerationCondenserWaterCooled_Impl.hpp
@@ -72,6 +72,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/SetpointManager.cpp b/src/model/SetpointManager.cpp
index cc40d2ff5ca..a8cfb5847d8 100644
--- a/src/model/SetpointManager.cpp
+++ b/src/model/SetpointManager.cpp
@@ -36,9 +36,11 @@
 #include "PlantLoop.hpp"
 #include "Splitter.hpp"
 #include "Mixer.hpp"
-#include <algorithm>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
+#include <algorithm>
 
 namespace openstudio {
 
@@ -177,13 +179,29 @@ namespace model {
       return boost::none;
     }
 
+    ComponentType SetpointManager_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> SetpointManager_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> SetpointManager_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> SetpointManager_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   SetpointManager::SetpointManager(IddObjectType type, const Model& model) : HVACComponent(type, model) {
     OS_ASSERT(getImpl<detail::SetpointManager_Impl>());
   }
 
-  SetpointManager::SetpointManager(std::shared_ptr<detail::SetpointManager_Impl> p) : HVACComponent(std::move(p)) {}
+  SetpointManager::SetpointManager(std::shared_ptr<detail::SetpointManager_Impl> impl) : HVACComponent(std::move(impl)) {}
 
   boost::optional<Node> SetpointManager::setpointNode() const {
     return getImpl<detail::SetpointManager_Impl>()->setpointNode();
diff --git a/src/model/SetpointManager_Impl.hpp b/src/model/SetpointManager_Impl.hpp
index 9aeb1e88849..bf7e8c1b5dc 100644
--- a/src/model/SetpointManager_Impl.hpp
+++ b/src/model/SetpointManager_Impl.hpp
@@ -89,6 +89,11 @@ namespace model {
      * If true, addToNode will allow connection on a PlantLoop (supply side, or demand side EXCEPT between splitter and mixer) */
       virtual bool isAllowedOnPlantLoop() const;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
      private:
       /** This is used to set the field SetpointNodeName.
       * Use addToNode to add a setpoint manager to a node. */
diff --git a/src/model/SolarCollectorFlatPlatePhotovoltaicThermal.cpp b/src/model/SolarCollectorFlatPlatePhotovoltaicThermal.cpp
index e12f4ea400d..413377c4796 100644
--- a/src/model/SolarCollectorFlatPlatePhotovoltaicThermal.cpp
+++ b/src/model/SolarCollectorFlatPlatePhotovoltaicThermal.cpp
@@ -47,13 +47,12 @@
 #include "Model.hpp"
 #include "AirLoopHVACOutdoorAirSystem.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_SolarCollector_FlatPlate_PhotovoltaicThermal_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -292,6 +291,22 @@ namespace model {
       }
     }
 
+    ComponentType SolarCollectorFlatPlatePhotovoltaicThermal_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> SolarCollectorFlatPlatePhotovoltaicThermal_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> SolarCollectorFlatPlatePhotovoltaicThermal_Impl::heatingFuelTypes() const {
+      return {FuelType::Solar};
+    }
+
+    std::vector<AppGFuelType> SolarCollectorFlatPlatePhotovoltaicThermal_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Solar};
+    }
+
   }  // namespace detail
 
   SolarCollectorFlatPlatePhotovoltaicThermal::SolarCollectorFlatPlatePhotovoltaicThermal(const Model& model)
diff --git a/src/model/SolarCollectorFlatPlatePhotovoltaicThermal_Impl.hpp b/src/model/SolarCollectorFlatPlatePhotovoltaicThermal_Impl.hpp
index 1013ad1c5b5..30fd1e93b59 100644
--- a/src/model/SolarCollectorFlatPlatePhotovoltaicThermal_Impl.hpp
+++ b/src/model/SolarCollectorFlatPlatePhotovoltaicThermal_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class GeneratorPhotovoltaic;
@@ -80,6 +81,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/SolarCollectorFlatPlateWater.cpp b/src/model/SolarCollectorFlatPlateWater.cpp
index 9aa2a0e549f..4fbc288d4ca 100644
--- a/src/model/SolarCollectorFlatPlateWater.cpp
+++ b/src/model/SolarCollectorFlatPlateWater.cpp
@@ -45,13 +45,12 @@
 #include "Node.hpp"
 #include "Model.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/OS_SolarCollector_FlatPlate_Water_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -198,6 +197,22 @@ namespace model {
       return setPointer(OS_SolarCollector_FlatPlate_WaterFields::SolarCollectorPerformanceName, solarCollectorPerformanceFlatPlate.handle());
     }
 
+    ComponentType SolarCollectorFlatPlateWater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> SolarCollectorFlatPlateWater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> SolarCollectorFlatPlateWater_Impl::heatingFuelTypes() const {
+      return {FuelType::Solar};
+    }
+
+    std::vector<AppGFuelType> SolarCollectorFlatPlateWater_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Solar};
+    }
+
   }  // namespace detail
 
   SolarCollectorFlatPlateWater::SolarCollectorFlatPlateWater(const Model& model)
diff --git a/src/model/SolarCollectorFlatPlateWater_Impl.hpp b/src/model/SolarCollectorFlatPlateWater_Impl.hpp
index 6c9dee07c3f..923e3a80bbc 100644
--- a/src/model/SolarCollectorFlatPlateWater_Impl.hpp
+++ b/src/model/SolarCollectorFlatPlateWater_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class SolarCollectorPerformanceFlatPlate;
@@ -78,6 +79,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/SolarCollectorIntegralCollectorStorage.cpp b/src/model/SolarCollectorIntegralCollectorStorage.cpp
index 48f59ef7339..c63ccd54ad0 100644
--- a/src/model/SolarCollectorIntegralCollectorStorage.cpp
+++ b/src/model/SolarCollectorIntegralCollectorStorage.cpp
@@ -42,13 +42,12 @@
 #include "Node_Impl.hpp"
 #include "Model.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_SolarCollector_IntegralCollectorStorage_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -214,6 +213,22 @@ namespace model {
       return setPointer(OS_SolarCollector_IntegralCollectorStorageFields::IntegralCollectorStorageParametersName, performance.handle());
     }
 
+    ComponentType SolarCollectorIntegralCollectorStorage_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> SolarCollectorIntegralCollectorStorage_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> SolarCollectorIntegralCollectorStorage_Impl::heatingFuelTypes() const {
+      return {FuelType::Solar};
+    }
+
+    std::vector<AppGFuelType> SolarCollectorIntegralCollectorStorage_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Solar};
+    }
+
   }  // namespace detail
 
   SolarCollectorIntegralCollectorStorage::SolarCollectorIntegralCollectorStorage(const Model& model)
diff --git a/src/model/SolarCollectorIntegralCollectorStorage_Impl.hpp b/src/model/SolarCollectorIntegralCollectorStorage_Impl.hpp
index 1d57dd5282f..305a1592fcf 100644
--- a/src/model/SolarCollectorIntegralCollectorStorage_Impl.hpp
+++ b/src/model/SolarCollectorIntegralCollectorStorage_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class PlanarSurface;
@@ -77,6 +78,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/SwimmingPoolIndoor.cpp b/src/model/SwimmingPoolIndoor.cpp
index 56b2b4c8758..e6ea6891f82 100644
--- a/src/model/SwimmingPoolIndoor.cpp
+++ b/src/model/SwimmingPoolIndoor.cpp
@@ -41,17 +41,15 @@
 #include "PlantLoop.hpp"
 #include "PlantLoop_Impl.hpp"
 #include "ScheduleRuleset.hpp"
-
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_SwimmingPool_Indoor_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -377,6 +375,22 @@ namespace model {
       return result;
     }
 
+    ComponentType SwimmingPoolIndoor_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> SwimmingPoolIndoor_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> SwimmingPoolIndoor_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> SwimmingPoolIndoor_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   SwimmingPoolIndoor::SwimmingPoolIndoor(const Model& model, const Surface& floorSurface)
diff --git a/src/model/SwimmingPoolIndoor_Impl.hpp b/src/model/SwimmingPoolIndoor_Impl.hpp
index 7e772fac744..0fa2ec022a1 100644
--- a/src/model/SwimmingPoolIndoor_Impl.hpp
+++ b/src/model/SwimmingPoolIndoor_Impl.hpp
@@ -73,6 +73,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/TemperingValve.cpp b/src/model/TemperingValve.cpp
index ddf574147a3..09d52f5a14f 100644
--- a/src/model/TemperingValve.cpp
+++ b/src/model/TemperingValve.cpp
@@ -41,9 +41,12 @@
 #include "HeaderedPumpsConstantSpeed_Impl.hpp"
 #include "HeaderedPumpsVariableSpeed.hpp"
 #include "HeaderedPumpsVariableSpeed_Impl.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_TemperingValve_FieldEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -206,6 +209,22 @@ namespace model {
       return StraightComponent_Impl::addToNode(node);
     }
 
+    ComponentType TemperingValve_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> TemperingValve_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> TemperingValve_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> TemperingValve_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   TemperingValve::TemperingValve(const Model& model) : StraightComponent(TemperingValve::iddObjectType(), model) {
diff --git a/src/model/TemperingValve_Impl.hpp b/src/model/TemperingValve_Impl.hpp
index 55024368b0c..632ef26e640 100644
--- a/src/model/TemperingValve_Impl.hpp
+++ b/src/model/TemperingValve_Impl.hpp
@@ -63,6 +63,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ThermalStorageChilledWaterStratified.cpp b/src/model/ThermalStorageChilledWaterStratified.cpp
index 31c080b991f..4f03d8358d1 100644
--- a/src/model/ThermalStorageChilledWaterStratified.cpp
+++ b/src/model/ThermalStorageChilledWaterStratified.cpp
@@ -39,14 +39,14 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+#include "../utilities/time/Time.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_ThermalStorage_ChilledWater_Stratified_FieldEnums.hxx>
 
-#include "../utilities/time/Time.hpp"
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -742,6 +742,25 @@ namespace model {
       }
     }
 
+    ComponentType ThermalStorageChilledWaterStratified_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ThermalStorageChilledWaterStratified_Impl::coolingFuelTypes() const {
+      if (auto p_ = secondaryPlantLoop()) {
+        return p_->coolingFuelTypes();
+      }
+      return {};
+    }
+
+    std::vector<FuelType> ThermalStorageChilledWaterStratified_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ThermalStorageChilledWaterStratified_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ThermalStorageChilledWaterStratified::ThermalStorageChilledWaterStratified(const Model& model)
diff --git a/src/model/ThermalStorageChilledWaterStratified_Impl.hpp b/src/model/ThermalStorageChilledWaterStratified_Impl.hpp
index 4f182b1acad..88914b79b0e 100644
--- a/src/model/ThermalStorageChilledWaterStratified_Impl.hpp
+++ b/src/model/ThermalStorageChilledWaterStratified_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -74,6 +75,15 @@ namespace model {
 
       virtual unsigned demandOutletPort() const override;
 
+      virtual void autosize() override;
+
+      virtual void applySizingValues() override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -166,10 +176,6 @@ namespace model {
 
       boost::optional<double> autosizedSourceSideDesignFlowRate() const;
 
-      virtual void autosize() override;
-
-      virtual void applySizingValues() override;
-
       //@}
       /** @name Setters */
       //@{
diff --git a/src/model/ThermalStorageIceDetailed.cpp b/src/model/ThermalStorageIceDetailed.cpp
index 7428d4ecf39..1a679c16d5e 100644
--- a/src/model/ThermalStorageIceDetailed.cpp
+++ b/src/model/ThermalStorageIceDetailed.cpp
@@ -43,10 +43,12 @@
 #include "CurveQuadraticLinear_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_ThermalStorage_Ice_Detailed_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -289,6 +291,22 @@ namespace model {
       return result;
     }
 
+    ComponentType ThermalStorageIceDetailed_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ThermalStorageIceDetailed_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ThermalStorageIceDetailed_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ThermalStorageIceDetailed_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ThermalStorageIceDetailed::ThermalStorageIceDetailed(const Model& model) : StraightComponent(ThermalStorageIceDetailed::iddObjectType(), model) {
diff --git a/src/model/ThermalStorageIceDetailed_Impl.hpp b/src/model/ThermalStorageIceDetailed_Impl.hpp
index ef8edd8d1a1..5d472082855 100644
--- a/src/model/ThermalStorageIceDetailed_Impl.hpp
+++ b/src/model/ThermalStorageIceDetailed_Impl.hpp
@@ -34,6 +34,7 @@
 #include "StraightComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -66,6 +67,18 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual unsigned inletPort() const override;
+      virtual unsigned outletPort() const override;
+
+      virtual bool addToNode(Node& node) override;
+      virtual std::vector<ModelObject> children() const override;
+      virtual ModelObject clone(Model model) const override;
+
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -128,13 +141,6 @@ namespace model {
       /** @name Other */
       //@{
 
-      virtual unsigned inletPort() const override;
-      virtual unsigned outletPort() const override;
-
-      bool addToNode(Node& node) override;
-      std::vector<ModelObject> children() const override;
-      ModelObject clone(Model model) const override;
-
       //@}
      protected:
      private:
diff --git a/src/model/ThermalZone.cpp b/src/model/ThermalZone.cpp
index d0e837b2b44..3fc975af96c 100644
--- a/src/model/ThermalZone.cpp
+++ b/src/model/ThermalZone.cpp
@@ -116,6 +116,7 @@
 
 #include "../utilities/core/Assert.hpp"
 #include "../utilities/core/ContainersMove.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/geometry/Transformation.hpp"
 #include "../utilities/geometry/Geometry.hpp"
 #include "../utilities/geometry/Point3d.hpp"
@@ -2697,6 +2698,61 @@ SELECT {} FROM ZoneSizes
       return boost::none;
     }
 
+    ComponentType ThermalZone_Impl::componentType() const {
+      bool has_cooling = false;
+      bool has_heating = false;
+      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {
+        auto compType = comp.componentType();
+        if (compType == ComponentType::Cooling) {
+          has_cooling = true;
+        } else if (compType == ComponentType::Heating) {
+          has_heating = true;
+        } else if (compType == ComponentType::Both) {
+          has_cooling = true;
+          has_heating = true;
+        }
+      }
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ThermalZone_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {
+        for (auto& ft : comp.coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ThermalZone_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {
+        for (auto& ft : comp.heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ThermalZone_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (const auto& comp : subsetCastVector<HVACComponent>(equipment())) {
+        for (auto& ft : comp.appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ThermalZone::ThermalZone(const Model& model) : HVACComponent(ThermalZone::iddObjectType(), model) {
diff --git a/src/model/ThermalZone_Impl.hpp b/src/model/ThermalZone_Impl.hpp
index 1f204b46d5f..cb7925ac2ee 100644
--- a/src/model/ThermalZone_Impl.hpp
+++ b/src/model/ThermalZone_Impl.hpp
@@ -95,6 +95,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       /** @name Getters */
       //@{
 
diff --git a/src/model/WaterHeaterHeatPump.cpp b/src/model/WaterHeaterHeatPump.cpp
index cae9a8e2eb8..79c5b94996a 100644
--- a/src/model/WaterHeaterHeatPump.cpp
+++ b/src/model/WaterHeaterHeatPump.cpp
@@ -52,10 +52,12 @@
 #include "ScheduleRuleset_Impl.hpp"
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
+
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_WaterHeater_HeatPump_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -544,6 +546,25 @@ namespace model {
       }
     }
 
+    // NOTE: The WaterHeaterHeatPump is listed as a ThermalZone equipment, but it's not a zone load.
+    // So we set everything to None/Empty here. It has a child Tank (WaterHeater:Mixed for eg), which WILL check if it's part of a HPWH
+    // so the PlantLoop's methods are affected accordingly though.
+    ComponentType WaterHeaterHeatPump_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> WaterHeaterHeatPump_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> WaterHeaterHeatPump_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> WaterHeaterHeatPump_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   WaterHeaterHeatPump::WaterHeaterHeatPump(const Model& model, const ModelObject& dxCoil, const HVACComponent& tank, const HVACComponent& fan,
diff --git a/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp b/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp
index e6b18b8ba14..ce87a55fc7f 100644
--- a/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp
+++ b/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp
@@ -54,14 +54,13 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_WaterHeater_HeatPump_WrappedCondenser_FieldEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
-#include "../utilities/core/Assert.hpp"
-
 namespace openstudio {
 namespace model {
 
@@ -560,6 +559,25 @@ namespace model {
       return result;
     }
 
+    // NOTE: The WaterHeaterHeatPumpWrappedCondenser is listed as a ThermalZone equipment, but it's not a zone load.
+    // So we set everything to None/Empty here. It has a child Tank (WaterHeater:Mixed for eg), which WILL check if it's part of a HPWH
+    // so the PlantLoop's methods are affected accordingly though.
+    ComponentType WaterHeaterHeatPumpWrappedCondenser_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> WaterHeaterHeatPumpWrappedCondenser_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> WaterHeaterHeatPumpWrappedCondenser_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> WaterHeaterHeatPumpWrappedCondenser_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   WaterHeaterHeatPumpWrappedCondenser::WaterHeaterHeatPumpWrappedCondenser(const Model& model)
diff --git a/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp b/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp
index 173d0aace51..e554912512c 100644
--- a/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp
+++ b/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/WaterHeaterHeatPump_Impl.hpp b/src/model/WaterHeaterHeatPump_Impl.hpp
index 98f62df4790..ae8d4ad3f01 100644
--- a/src/model/WaterHeaterHeatPump_Impl.hpp
+++ b/src/model/WaterHeaterHeatPump_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/WaterHeaterMixed.cpp b/src/model/WaterHeaterMixed.cpp
index 992b6eb733f..457e14ef838 100644
--- a/src/model/WaterHeaterMixed.cpp
+++ b/src/model/WaterHeaterMixed.cpp
@@ -50,11 +50,13 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/units/Unit.hpp"
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_WaterHeater_Mixed_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 #include <algorithm>
 
@@ -1392,6 +1394,93 @@ namespace model {
       return demandOutletModelObject();
     }
 
+    ComponentType WaterHeaterMixed_Impl::componentType() const {
+      if (boost::optional<double> _cap = heaterMaximumCapacity()) {
+        if (_cap.get() == 0.0) {
+          // Capacity is zero: it's a storage tank!
+          // get the Source loop
+          if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+            // I guess we could rely on Heating/Cooling/Condenser set in the sizingPlant
+            // if ( openstudio::istringEqual(p->sizingPlant().loopType(), "Heating") { }
+            // Might be better to do a recursive call to see what type of equipment you have on the supply side of the plant loop though
+            return p_->componentType();
+
+            // We also need to check if the tank isn't attached to a HPWH, in which case we return Heating
+            // There's some magic later that'll put the HPWH itself and not the tank on the PlantEquipmentOperation,
+            // see function operationSchemeComponent()
+          } else if (boost::optional<ZoneHVACComponent> zoneComp_ = containingZoneHVACComponent()) {
+            // We don't have to explicitly check if it's a WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser since
+            // these are the only two types of zoneHVACComponent that could have a WaterHeater object, but this might change in the future
+            IddObjectType zoneCompIdd = zoneComp_->iddObjectType();
+            if ((zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump)
+                || (zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump_WrappedCondenser)) {
+              return ComponentType::Heating;
+            } else {
+              OS_ASSERT(false);
+              return ComponentType::None;
+            }
+          } else {
+            // It isn't connected to a source side, and has zero capacity, and not part of HPWH => it's a buffer tank => NONE
+            return ComponentType::None;
+          }  // End if has source loop
+
+        } else {
+          // If there is a capacity, and it's not zero, it's heating
+          return ComponentType::Heating;
+        }  // End cap == 0
+
+      } else {
+        // If autosize, then it's Heating
+        return ComponentType::Heating;
+      }  // end has a heater capacity
+    }
+
+    std::vector<FuelType> WaterHeaterMixed_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->coolingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> WaterHeaterMixed_Impl::heatingFuelTypes() const {
+
+      std::set<FuelType> result;
+      if (boost::optional<double> _cap = heaterMaximumCapacity(); _cap.get() > 0.0) {
+        result.insert(FuelType(heaterFuelType()));
+      }
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->heatingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+      if (auto zoneComp_ = containingZoneHVACComponent()) {
+        // The only accepted types are the WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser so skip the checks
+        result.insert(FuelType::Electricity);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> WaterHeaterMixed_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (boost::optional<double> _cap = heaterMaximumCapacity(); _cap.get() > 0.0) {
+        result.insert(convertFuelTypeToAppG(FuelType(heaterFuelType())));
+      }
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->appGHeatingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+      if (auto zoneComp_ = containingZoneHVACComponent()) {
+        // The only accepted types are the WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser so skip the checks
+        result.insert(AppGFuelType::HeatPump);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   WaterHeaterMixed::WaterHeaterMixed(const Model& model) : WaterToWaterComponent(WaterHeaterMixed::iddObjectType(), model) {
diff --git a/src/model/WaterHeaterMixed_Impl.hpp b/src/model/WaterHeaterMixed_Impl.hpp
index 4f6b367c0b2..63472d788d9 100644
--- a/src/model/WaterHeaterMixed_Impl.hpp
+++ b/src/model/WaterHeaterMixed_Impl.hpp
@@ -99,6 +99,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/WaterHeaterStratified.cpp b/src/model/WaterHeaterStratified.cpp
index e801076a9ab..3eabb581c8e 100644
--- a/src/model/WaterHeaterStratified.cpp
+++ b/src/model/WaterHeaterStratified.cpp
@@ -52,10 +52,11 @@
 #include "Node.hpp"
 #include "Node_Impl.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/OS_WaterHeater_Stratified_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 #include <algorithm>
 
@@ -1369,6 +1370,89 @@ namespace model {
       return demandOutletModelObject();
     }
 
+    ComponentType WaterHeaterStratified_Impl::componentType() const {
+
+      if (isHeater1CapacityAutosized() || ((heater1Capacity().get() + heater2Capacity()) > 0.01)) {
+        // If there is a capacity, and it's not zero, it's heating
+        return ComponentType::Heating;
+      }
+
+      // Capacity is zero: it's a storage tank! get the Source loop
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        return p_->componentType();
+
+        // We also need to check if the tank isn't attached to a HPWH, in which case we return Heating
+        // There's some magic later that'll put the HPWH itself and not the tank on the PlantEquipmentOperation,
+        // see function operationSchemeComponent()
+      } else if (boost::optional<ZoneHVACComponent> zoneComp_ = containingZoneHVACComponent()) {
+        // We don't have to explicitly check if it's a WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser since
+        // these are the only two types of zoneHVACComponent that could have a WaterHeater object, but this might change in the future
+        IddObjectType zoneCompIdd = zoneComp_->iddObjectType();
+        if ((zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump)
+            || (zoneCompIdd == openstudio::IddObjectType::OS_WaterHeater_HeatPump_WrappedCondenser)) {
+          return ComponentType::Heating;
+        } else {
+          OS_ASSERT(false);
+          return ComponentType::None;
+        }
+      }
+
+      // It isn't connected to a source side, and has zero capacity, and not part of HPWH => it's a buffer tank => NONE
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> WaterHeaterStratified_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+
+      // TODO: only if cap == 0?
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->coolingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> WaterHeaterStratified_Impl::heatingFuelTypes() const {
+
+      std::set<FuelType> result;
+
+      if (isHeater1CapacityAutosized() || ((heater1Capacity().get() + heater2Capacity()) > 0.01)) {
+        // If there is a capacity, and it's not zero, it's heating
+        result.insert(FuelType(heaterFuelType()));
+      }
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->heatingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+      if (auto zoneComp_ = containingZoneHVACComponent()) {
+        // The only accepted types are the WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser so skip the checks
+        result.insert(FuelType::Electricity);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> WaterHeaterStratified_Impl::appGHeatingFuelTypes() const {
+
+      std::set<AppGFuelType> result;
+
+      if (isHeater1CapacityAutosized() || ((heater1Capacity().get() + heater2Capacity()) > 0.01)) {
+        // If there is a capacity, and it's not zero, it's heating
+        result.insert(convertFuelTypeToAppG(FuelType(heaterFuelType())));
+      }
+      if (boost::optional<PlantLoop> p_ = secondaryPlantLoop()) {
+        auto plantFuelTypes = p_->appGHeatingFuelTypes();
+        result.insert(plantFuelTypes.begin(), plantFuelTypes.end());
+      }
+      if (auto zoneComp_ = containingZoneHVACComponent()) {
+        // The only accepted types are the WaterHeaterHeatPump or WaterHeaterHeatPumpWrappedCondenser so skip the checks
+        result.insert(AppGFuelType::HeatPump);
+      }
+
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   WaterHeaterStratified::WaterHeaterStratified(const Model& model) : WaterToWaterComponent(WaterHeaterStratified::iddObjectType(), model) {
diff --git a/src/model/WaterHeaterStratified_Impl.hpp b/src/model/WaterHeaterStratified_Impl.hpp
index ed0b8bc9bac..93efe2a3b72 100644
--- a/src/model/WaterHeaterStratified_Impl.hpp
+++ b/src/model/WaterHeaterStratified_Impl.hpp
@@ -34,6 +34,7 @@
 #include "WaterToWaterComponent_Impl.hpp"
 
 namespace openstudio {
+
 namespace model {
 
   class Schedule;
@@ -97,6 +98,11 @@ namespace model {
 
       virtual bool addToNode(Node& node) override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/WaterUseConnections.cpp b/src/model/WaterUseConnections.cpp
index 8d50a62195f..aa39d979fdb 100644
--- a/src/model/WaterUseConnections.cpp
+++ b/src/model/WaterUseConnections.cpp
@@ -42,12 +42,13 @@
 #include "PlantLoop_Impl.hpp"
 #include <utilities/idd/IddFactory.hxx>
 
-#include <utilities/idd/OS_WaterUse_Connections_FieldEnums.hxx>
-#include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 #include "../utilities/idf/WorkspaceExtensibleGroup.hpp"
 
+#include <utilities/idd/OS_WaterUse_Connections_FieldEnums.hxx>
+#include <utilities/idd/IddEnums.hxx>
+
 namespace openstudio {
 
 namespace model {
@@ -292,6 +293,22 @@ namespace model {
       OS_ASSERT(result);
     }
 
+    ComponentType WaterUseConnections_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> WaterUseConnections_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> WaterUseConnections_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> WaterUseConnections_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   WaterUseConnections::WaterUseConnections(const Model& model) : StraightComponent(WaterUseConnections::iddObjectType(), model) {
diff --git a/src/model/WaterUseConnections_Impl.hpp b/src/model/WaterUseConnections_Impl.hpp
index 63b14465715..f18eab1c03a 100644
--- a/src/model/WaterUseConnections_Impl.hpp
+++ b/src/model/WaterUseConnections_Impl.hpp
@@ -59,6 +59,11 @@ namespace model {
 
       virtual IddObjectType iddObjectType() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
       boost::optional<Schedule> hotWaterSupplyTemperatureSchedule() const;
diff --git a/src/model/ZoneHVACBaseboardConvectiveElectric.cpp b/src/model/ZoneHVACBaseboardConvectiveElectric.cpp
index 0cf44788a3a..e6a8ca82bac 100644
--- a/src/model/ZoneHVACBaseboardConvectiveElectric.cpp
+++ b/src/model/ZoneHVACBaseboardConvectiveElectric.cpp
@@ -38,8 +38,8 @@
 #include "ScheduleTypeRegistry.hpp"
 #include <utilities/idd/OS_ZoneHVAC_Baseboard_Convective_Electric_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -237,6 +237,22 @@ namespace model {
       return types;
     }
 
+    ComponentType ZoneHVACBaseboardConvectiveElectric_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardConvectiveElectric_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardConvectiveElectric_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACBaseboardConvectiveElectric_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   ZoneHVACBaseboardConvectiveElectric::ZoneHVACBaseboardConvectiveElectric(const Model& model)
diff --git a/src/model/ZoneHVACBaseboardConvectiveElectric_Impl.hpp b/src/model/ZoneHVACBaseboardConvectiveElectric_Impl.hpp
index ebb78004408..e8ba2d28d2c 100644
--- a/src/model/ZoneHVACBaseboardConvectiveElectric_Impl.hpp
+++ b/src/model/ZoneHVACBaseboardConvectiveElectric_Impl.hpp
@@ -66,6 +66,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACBaseboardConvectiveWater.cpp b/src/model/ZoneHVACBaseboardConvectiveWater.cpp
index fa7b1b6c1a7..00634821fbb 100644
--- a/src/model/ZoneHVACBaseboardConvectiveWater.cpp
+++ b/src/model/ZoneHVACBaseboardConvectiveWater.cpp
@@ -48,6 +48,7 @@
 #include <utilities/idd/IddEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -253,6 +254,22 @@ namespace model {
       return types;
     }
 
+    ComponentType ZoneHVACBaseboardConvectiveWater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardConvectiveWater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardConvectiveWater_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> ZoneHVACBaseboardConvectiveWater_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   ZoneHVACBaseboardConvectiveWater::ZoneHVACBaseboardConvectiveWater(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/ZoneHVACBaseboardConvectiveWater_Impl.hpp b/src/model/ZoneHVACBaseboardConvectiveWater_Impl.hpp
index 65211fe0790..021c14acd59 100644
--- a/src/model/ZoneHVACBaseboardConvectiveWater_Impl.hpp
+++ b/src/model/ZoneHVACBaseboardConvectiveWater_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
 
       virtual std::vector<ModelObject> children() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp
index ba776a48ea6..2ea76d63d57 100644
--- a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp
+++ b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp
@@ -45,6 +45,7 @@
 #include <utilities/idd/OS_ZoneHVAC_Baseboard_RadiantConvective_Electric_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -294,6 +295,23 @@ namespace model {
       std::vector<std::string> types{"Simple Zone Baseboard Capacity At Low Temperature", "Simple Zone Baseboard Capacity At High Temperature"};
       return types;
     }
+
+    ComponentType ZoneHVACBaseboardRadiantConvectiveElectric_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardRadiantConvectiveElectric_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardRadiantConvectiveElectric_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACBaseboardRadiantConvectiveElectric_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   ZoneHVACBaseboardRadiantConvectiveElectric::ZoneHVACBaseboardRadiantConvectiveElectric(const Model& model)
diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp
index d3793133a59..5022d974927 100644
--- a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp
+++ b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       void removeFromThermalZone() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp
index b51530ee986..f995a845dd6 100644
--- a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp
+++ b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp
@@ -49,6 +49,7 @@
 #include <utilities/idd/OS_ZoneHVAC_Baseboard_RadiantConvective_Water_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -258,6 +259,23 @@ namespace model {
       std::vector<std::string> types{"Simple Zone Baseboard Capacity At Low Temperature", "Simple Zone Baseboard Capacity At High Temperature"};
       return types;
     }
+
+    ComponentType ZoneHVACBaseboardRadiantConvectiveWater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardRadiantConvectiveWater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACBaseboardRadiantConvectiveWater_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> ZoneHVACBaseboardRadiantConvectiveWater_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   ZoneHVACBaseboardRadiantConvectiveWater::ZoneHVACBaseboardRadiantConvectiveWater(const Model& model)
diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp
index 600c63a76b3..da450c93b1b 100644
--- a/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp
+++ b/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp
@@ -84,6 +84,11 @@ namespace model {
 
       virtual std::vector<IdfObject> remove() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp
index 48d4024fc12..78b53025f2d 100644
--- a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp
+++ b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp
@@ -49,6 +49,7 @@
 #include <utilities/idd/OS_ZoneHVAC_CoolingPanel_RadiantConvective_Water_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -261,6 +262,23 @@ namespace model {
       std::vector<std::string> types{"Simple Zone CoolingPanel Capacity At Low Temperature", "Simple Zone CoolingPanel Capacity At High Temperature"};
       return types;
     }
+
+    ComponentType ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::componentType() const {
+      return ComponentType::Cooling;
+    }
+
+    std::vector<FuelType> ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ZoneHVACCoolingPanelRadiantConvectiveWater::ZoneHVACCoolingPanelRadiantConvectiveWater(const Model& model)
diff --git a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp
index 971df178567..87d23e0576b 100644
--- a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp
+++ b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp
@@ -85,6 +85,11 @@ namespace model {
 
       virtual std::vector<IdfObject> remove() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACDehumidifierDX.cpp b/src/model/ZoneHVACDehumidifierDX.cpp
index 9e14aeb5f41..1ad813e67bb 100644
--- a/src/model/ZoneHVACDehumidifierDX.cpp
+++ b/src/model/ZoneHVACDehumidifierDX.cpp
@@ -46,6 +46,7 @@
 #include <utilities/idd/OS_ZoneHVAC_Dehumidifier_DX_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -290,6 +291,22 @@ namespace model {
       return getObject<ModelObject>().getModelObjectTarget<Curve>(OS_ZoneHVAC_Dehumidifier_DXFields::PartLoadFractionCorrelationCurveName);
     }
 
+    ComponentType ZoneHVACDehumidifierDX_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneHVACDehumidifierDX_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACDehumidifierDX_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACDehumidifierDX_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ZoneHVACDehumidifierDX::ZoneHVACDehumidifierDX(const Model& model) : ZoneHVACComponent(ZoneHVACDehumidifierDX::iddObjectType(), model) {
diff --git a/src/model/ZoneHVACDehumidifierDX_Impl.hpp b/src/model/ZoneHVACDehumidifierDX_Impl.hpp
index 8eac495e115..403d736720b 100644
--- a/src/model/ZoneHVACDehumidifierDX_Impl.hpp
+++ b/src/model/ZoneHVACDehumidifierDX_Impl.hpp
@@ -73,6 +73,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACEnergyRecoveryVentilator.cpp b/src/model/ZoneHVACEnergyRecoveryVentilator.cpp
index e62a127282d..abcbc83b89e 100644
--- a/src/model/ZoneHVACEnergyRecoveryVentilator.cpp
+++ b/src/model/ZoneHVACEnergyRecoveryVentilator.cpp
@@ -48,6 +48,7 @@
 #include <utilities/idd/OS_ZoneHVAC_EnergyRecoveryVentilator_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -363,6 +364,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACEnergyRecoveryVentilator_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneHVACEnergyRecoveryVentilator_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACEnergyRecoveryVentilator_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACEnergyRecoveryVentilator_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ZoneHVACEnergyRecoveryVentilator::ZoneHVACEnergyRecoveryVentilator(const Model& model)
diff --git a/src/model/ZoneHVACEnergyRecoveryVentilator_Impl.hpp b/src/model/ZoneHVACEnergyRecoveryVentilator_Impl.hpp
index c91e0ca116d..42c47a05813 100644
--- a/src/model/ZoneHVACEnergyRecoveryVentilator_Impl.hpp
+++ b/src/model/ZoneHVACEnergyRecoveryVentilator_Impl.hpp
@@ -75,6 +75,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACFourPipeFanCoil.cpp b/src/model/ZoneHVACFourPipeFanCoil.cpp
index 04ff8a20109..87bf6ffd2e1 100644
--- a/src/model/ZoneHVACFourPipeFanCoil.cpp
+++ b/src/model/ZoneHVACFourPipeFanCoil.cpp
@@ -47,9 +47,8 @@
 #include <utilities/idd/OS_ZoneHVAC_FourPipeFanCoil_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -786,6 +785,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACFourPipeFanCoil_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACFourPipeFanCoil_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> ZoneHVACFourPipeFanCoil_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> ZoneHVACFourPipeFanCoil_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   ZoneHVACFourPipeFanCoil::ZoneHVACFourPipeFanCoil(const Model& model, Schedule& availabilitySchedule, HVACComponent& supplyAirFan,
diff --git a/src/model/ZoneHVACFourPipeFanCoil_Impl.hpp b/src/model/ZoneHVACFourPipeFanCoil_Impl.hpp
index 9396a5939c0..33313534250 100644
--- a/src/model/ZoneHVACFourPipeFanCoil_Impl.hpp
+++ b/src/model/ZoneHVACFourPipeFanCoil_Impl.hpp
@@ -77,6 +77,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACHighTemperatureRadiant.cpp b/src/model/ZoneHVACHighTemperatureRadiant.cpp
index 70ff4454d5f..ff85501c00f 100644
--- a/src/model/ZoneHVACHighTemperatureRadiant.cpp
+++ b/src/model/ZoneHVACHighTemperatureRadiant.cpp
@@ -45,8 +45,8 @@
 
 #include <utilities/idd/OS_ZoneHVAC_HighTemperatureRadiant_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -331,6 +331,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACHighTemperatureRadiant_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACHighTemperatureRadiant_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACHighTemperatureRadiant_Impl::heatingFuelTypes() const {
+      return {FuelType(fuelType())};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACHighTemperatureRadiant_Impl::appGHeatingFuelTypes() const {
+      return {convertFuelTypeToAppG(FuelType(fuelType()))};
+    }
+
   }  // namespace detail
 
   ZoneHVACHighTemperatureRadiant::ZoneHVACHighTemperatureRadiant(const Model& model)
diff --git a/src/model/ZoneHVACHighTemperatureRadiant_Impl.hpp b/src/model/ZoneHVACHighTemperatureRadiant_Impl.hpp
index 2119e669e39..c3549c29915 100644
--- a/src/model/ZoneHVACHighTemperatureRadiant_Impl.hpp
+++ b/src/model/ZoneHVACHighTemperatureRadiant_Impl.hpp
@@ -65,6 +65,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACIdealLoadsAirSystem.cpp b/src/model/ZoneHVACIdealLoadsAirSystem.cpp
index 790db2ec2f0..a735dca05d0 100644
--- a/src/model/ZoneHVACIdealLoadsAirSystem.cpp
+++ b/src/model/ZoneHVACIdealLoadsAirSystem.cpp
@@ -40,9 +40,8 @@
 #include <utilities/idd/OS_ZoneHVAC_IdealLoadsAirSystem_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -813,6 +812,22 @@ namespace model {
       return types;
     }
 
+    ComponentType ZoneHVACIdealLoadsAirSystem_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACIdealLoadsAirSystem_Impl::coolingFuelTypes() const {
+      return {FuelType::DistrictCooling};
+    }
+
+    std::vector<FuelType> ZoneHVACIdealLoadsAirSystem_Impl::heatingFuelTypes() const {
+      return {FuelType::DistrictHeating};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACIdealLoadsAirSystem_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::District};
+    }
+
   }  // namespace detail
 
   ZoneHVACIdealLoadsAirSystem::ZoneHVACIdealLoadsAirSystem(const Model& model)
diff --git a/src/model/ZoneHVACIdealLoadsAirSystem_Impl.hpp b/src/model/ZoneHVACIdealLoadsAirSystem_Impl.hpp
index 30aa9a6f066..c59220ecf9b 100644
--- a/src/model/ZoneHVACIdealLoadsAirSystem_Impl.hpp
+++ b/src/model/ZoneHVACIdealLoadsAirSystem_Impl.hpp
@@ -71,6 +71,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACLowTempRadiantConstFlow.cpp b/src/model/ZoneHVACLowTempRadiantConstFlow.cpp
index d0a822a6c0c..332f1d4e5d7 100644
--- a/src/model/ZoneHVACLowTempRadiantConstFlow.cpp
+++ b/src/model/ZoneHVACLowTempRadiantConstFlow.cpp
@@ -57,9 +57,8 @@
 #include <utilities/idd/OS_ZoneHVAC_LowTemperatureRadiant_ConstantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -712,6 +711,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACLowTempRadiantConstFlow_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACLowTempRadiantConstFlow_Impl::coolingFuelTypes() const {
+      return coolingCoil().coolingFuelTypes();
+    }
+
+    std::vector<FuelType> ZoneHVACLowTempRadiantConstFlow_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> ZoneHVACLowTempRadiantConstFlow_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   ZoneHVACLowTempRadiantConstFlow::ZoneHVACLowTempRadiantConstFlow(const Model& model, Schedule& availabilitySchedule, HVACComponent& heatingCoil,
diff --git a/src/model/ZoneHVACLowTempRadiantConstFlow_Impl.hpp b/src/model/ZoneHVACLowTempRadiantConstFlow_Impl.hpp
index 94483a46108..be666a7432d 100644
--- a/src/model/ZoneHVACLowTempRadiantConstFlow_Impl.hpp
+++ b/src/model/ZoneHVACLowTempRadiantConstFlow_Impl.hpp
@@ -86,6 +86,11 @@ namespace model {
 
       virtual void applySizingValues() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACLowTempRadiantVarFlow.cpp b/src/model/ZoneHVACLowTempRadiantVarFlow.cpp
index d20b6829cce..4444c090907 100644
--- a/src/model/ZoneHVACLowTempRadiantVarFlow.cpp
+++ b/src/model/ZoneHVACLowTempRadiantVarFlow.cpp
@@ -57,9 +57,8 @@
 #include <utilities/idd/OS_ZoneHVAC_LowTemperatureRadiant_VariableFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -576,6 +575,50 @@ namespace model {
       return types;
     }
 
+    ComponentType ZoneHVACLowTempRadiantVarFlow_Impl::componentType() const {
+      const bool has_cooling = heatingCoil().has_value();
+      const bool has_heating = coolingCoil().has_value();
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneHVACLowTempRadiantVarFlow_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACLowTempRadiantVarFlow_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACLowTempRadiantVarFlow_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACLowTempRadiantVarFlow::ZoneHVACLowTempRadiantVarFlow(const Model& model, Schedule& availabilitySchedule, HVACComponent& heatingCoil,
diff --git a/src/model/ZoneHVACLowTempRadiantVarFlow_Impl.hpp b/src/model/ZoneHVACLowTempRadiantVarFlow_Impl.hpp
index 494c6ad32db..ffc148f4e16 100644
--- a/src/model/ZoneHVACLowTempRadiantVarFlow_Impl.hpp
+++ b/src/model/ZoneHVACLowTempRadiantVarFlow_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACLowTemperatureRadiantElectric.cpp b/src/model/ZoneHVACLowTemperatureRadiantElectric.cpp
index dce31e3227a..de6d24efddb 100644
--- a/src/model/ZoneHVACLowTemperatureRadiantElectric.cpp
+++ b/src/model/ZoneHVACLowTemperatureRadiantElectric.cpp
@@ -49,8 +49,8 @@
 #include <utilities/idd/OS_ZoneHVAC_LowTemperatureRadiant_Electric_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -398,6 +398,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACLowTemperatureRadiantElectric_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACLowTemperatureRadiantElectric_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACLowTemperatureRadiantElectric_Impl::heatingFuelTypes() const {
+      return {FuelType::Electricity};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACLowTemperatureRadiantElectric_Impl::appGHeatingFuelTypes() const {
+      return {AppGFuelType::Electric};
+    }
+
   }  // namespace detail
 
   ZoneHVACLowTemperatureRadiantElectric::ZoneHVACLowTemperatureRadiantElectric(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/ZoneHVACLowTemperatureRadiantElectric_Impl.hpp b/src/model/ZoneHVACLowTemperatureRadiantElectric_Impl.hpp
index 551afa8cc56..a7fc9566867 100644
--- a/src/model/ZoneHVACLowTemperatureRadiantElectric_Impl.hpp
+++ b/src/model/ZoneHVACLowTemperatureRadiantElectric_Impl.hpp
@@ -139,6 +139,11 @@ namespace model {
 
       void removeFromThermalZone() override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Other */
       //@{
diff --git a/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp b/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp
index 31921a11d24..eb34bb62468 100644
--- a/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp
+++ b/src/model/ZoneHVACPackagedTerminalAirConditioner.cpp
@@ -46,6 +46,7 @@
 #include <utilities/idd/IddEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -680,6 +681,34 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACPackagedTerminalAirConditioner_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACPackagedTerminalAirConditioner_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : coolingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACPackagedTerminalAirConditioner_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACPackagedTerminalAirConditioner_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACPackagedTerminalAirConditioner::ZoneHVACPackagedTerminalAirConditioner(const Model& model, Schedule& availabilitySchedule,
diff --git a/src/model/ZoneHVACPackagedTerminalAirConditioner_Impl.hpp b/src/model/ZoneHVACPackagedTerminalAirConditioner_Impl.hpp
index 9524483fd43..45f78de26c2 100644
--- a/src/model/ZoneHVACPackagedTerminalAirConditioner_Impl.hpp
+++ b/src/model/ZoneHVACPackagedTerminalAirConditioner_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACPackagedTerminalHeatPump.cpp b/src/model/ZoneHVACPackagedTerminalHeatPump.cpp
index d9a03af2a4c..3634171bc30 100644
--- a/src/model/ZoneHVACPackagedTerminalHeatPump.cpp
+++ b/src/model/ZoneHVACPackagedTerminalHeatPump.cpp
@@ -45,6 +45,7 @@
 #include <utilities/idd/IddEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -833,6 +834,40 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACPackagedTerminalHeatPump_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACPackagedTerminalHeatPump_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : coolingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACPackagedTerminalHeatPump_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACPackagedTerminalHeatPump_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACPackagedTerminalHeatPump::ZoneHVACPackagedTerminalHeatPump(const Model& model, Schedule& availabilitySchedule, HVACComponent& supplyAirFan,
diff --git a/src/model/ZoneHVACPackagedTerminalHeatPump_Impl.hpp b/src/model/ZoneHVACPackagedTerminalHeatPump_Impl.hpp
index ecd38604e7d..cd16b0910f4 100644
--- a/src/model/ZoneHVACPackagedTerminalHeatPump_Impl.hpp
+++ b/src/model/ZoneHVACPackagedTerminalHeatPump_Impl.hpp
@@ -77,6 +77,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.cpp b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.cpp
index 7b082eedfa6..6f1d45405e0 100644
--- a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.cpp
+++ b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.cpp
@@ -56,13 +56,19 @@
 #include "AirLoopHVACOutdoorAirSystem.hpp"
 #include "HVACComponent.hpp"
 #include "HVACComponent_Impl.hpp"
+#include "AirConditionerVariableRefrigerantFlow.hpp"
+#include "AirConditionerVariableRefrigerantFlow_Impl.hpp"
+#include "AirConditionerVariableRefrigerantFlowFluidTemperatureControl.hpp"
+#include "AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Impl.hpp"
+#include "AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR.hpp"
+#include "AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Impl.hpp"
 
 #include <utilities/idd/IddFactory.hxx>
 
 #include <utilities/idd/OS_ZoneHVAC_TerminalUnit_VariableRefrigerantFlow_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 
@@ -810,6 +816,111 @@ namespace model {
       return types;
     }
 
+    boost::optional<HVACComponent> ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl::vrfSystem() const {
+
+      if (isFluidTemperatureControl()) {
+
+        for (const auto& vrfSys : this->model().getConcreteModelObjects<AirConditionerVariableRefrigerantFlowFluidTemperatureControl>()) {
+          for (const auto& term : vrfSys.terminals()) {
+            if (term.handle() == this->handle()) {
+              return vrfSys;
+            }
+          }
+        }
+
+        for (const auto& vrfSys : this->model().getConcreteModelObjects<AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR>()) {
+          for (const auto& term : vrfSys.terminals()) {
+            if (term.handle() == this->handle()) {
+              return vrfSys;
+            }
+          }
+        }
+
+      } else {
+        for (const auto& vrfSys : this->model().getConcreteModelObjects<AirConditionerVariableRefrigerantFlow>()) {
+          for (const auto& term : vrfSys.terminals()) {
+            if (term.handle() == this->handle()) {
+              return vrfSys;
+            }
+          }
+        }
+      }
+
+      return boost::none;
+    }
+
+    ComponentType ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl::componentType() const {
+      const bool has_cooling = coolingCoil().is_initialized();
+      const bool has_heating = heatingCoil().is_initialized();
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto vrfSys_ = vrfSystem()) {
+        for (auto ft : vrfSys_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto supHC_ = supplementalHeatingCoil()) {
+        for (auto ft : supHC_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto vrfSys_ = vrfSystem()) {
+        for (auto ft : vrfSys_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto supHC_ = supplementalHeatingCoil()) {
+        for (auto ft : supHC_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      if (auto vrfSys_ = vrfSystem()) {
+        for (auto ft : vrfSys_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACTerminalUnitVariableRefrigerantFlow::ZoneHVACTerminalUnitVariableRefrigerantFlow(const Model& model, bool isFluidTemperatureControl)
@@ -1285,5 +1396,9 @@ namespace model {
     return getImpl<detail::ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl>()->autosizedMaximumSupplyAirTemperaturefromSupplementalHeater();
   }
 
+  boost::optional<HVACComponent> ZoneHVACTerminalUnitVariableRefrigerantFlow::vrfSystem() const {
+    return getImpl<detail::ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl>()->vrfSystem();
+  }
+
 }  // namespace model
 }  // namespace openstudio
diff --git a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp
index 699da1cd78a..c699c129846 100644
--- a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp
+++ b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp
@@ -165,9 +165,6 @@ namespace model {
     // Using a single type of coils is enforced: both must be FluidTemperatureControl or Non-FluidCtrl
     bool setHeatingCoil(const HVACComponent& coil);
 
-    // Returns true if the Cooling and Heating Coils are of the FluidTemperatureControl type
-    bool isFluidTemperatureControl() const;
-
     double zoneTerminalUnitOnParasiticElectricEnergyUse() const;
 
     bool setZoneTerminalUnitOnParasiticElectricEnergyUse(double zoneTerminalUnitOnParasiticElectricEnergyUse);
@@ -223,6 +220,19 @@ namespace model {
 
     boost::optional<double> autosizedMaximumSupplyAirTemperaturefromSupplementalHeater() const;
 
+    //@}
+    /** @name Other */
+    //@{
+
+    // Returns true if the Cooling and Heating Coils are of the FluidTemperatureControl type
+    bool isFluidTemperatureControl() const;
+
+    /** Convenience function to return parent VRF System:
+     * - AirConditionerVariableRefrigerantFlow
+     * - AirConditionerVariableRefrigerantFlowFluidTemperatureControl
+     * - AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR */
+    boost::optional<HVACComponent> vrfSystem() const;
+
    protected:
     /// @cond
     using ImplType = detail::ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl;
diff --git a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp
index 06909971473..06275376c55 100644
--- a/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp
+++ b/src/model/ZoneHVACTerminalUnitVariableRefrigerantFlow_Impl.hpp
@@ -88,6 +88,11 @@ namespace model {
 
       virtual std::vector<ModelObject> children() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
@@ -218,10 +223,6 @@ namespace model {
 
       bool setRatedTotalHeatingCapacitySizingRatio(double ratedTotalHeatingCapacitySizingRatio);
 
-      //@}
-      /** @name Other */
-      //@{
-
       bool setSupplyAirFan(const HVACComponent& component);
       void resetSupplyAirFan();
 
@@ -229,9 +230,15 @@ namespace model {
 
       bool setHeatingCoil(const HVACComponent& component);
 
+      //@}
+      /** @name Other */
+      //@{
+
       // Returns true if the Cooling and Heating Coils are of the FluidTemperatureControl type
       bool isFluidTemperatureControl() const;
 
+      boost::optional<HVACComponent> vrfSystem() const;
+
       //@}
      protected:
      private:
diff --git a/src/model/ZoneHVACUnitHeater.cpp b/src/model/ZoneHVACUnitHeater.cpp
index e34155404de..fcf0a9b58c7 100644
--- a/src/model/ZoneHVACUnitHeater.cpp
+++ b/src/model/ZoneHVACUnitHeater.cpp
@@ -46,8 +46,8 @@
 #include <utilities/idd/OS_ZoneHVAC_UnitHeater_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -385,6 +385,22 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACUnitHeater_Impl::componentType() const {
+      return ComponentType::Heating;
+    }
+
+    std::vector<FuelType> ZoneHVACUnitHeater_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneHVACUnitHeater_Impl::heatingFuelTypes() const {
+      return heatingCoil().heatingFuelTypes();
+    }
+
+    std::vector<AppGFuelType> ZoneHVACUnitHeater_Impl::appGHeatingFuelTypes() const {
+      return heatingCoil().appGHeatingFuelTypes();
+    }
+
   }  // namespace detail
 
   ZoneHVACUnitHeater::ZoneHVACUnitHeater(const Model& model, Schedule& availabilitySchedule, HVACComponent& supplyAirFan, HVACComponent& heatingCoil)
diff --git a/src/model/ZoneHVACUnitHeater_Impl.hpp b/src/model/ZoneHVACUnitHeater_Impl.hpp
index a657dd2a1f5..4088e81d5b6 100644
--- a/src/model/ZoneHVACUnitHeater_Impl.hpp
+++ b/src/model/ZoneHVACUnitHeater_Impl.hpp
@@ -76,6 +76,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACUnitVentilator.cpp b/src/model/ZoneHVACUnitVentilator.cpp
index 92c44175cb6..11d7a97b0db 100644
--- a/src/model/ZoneHVACUnitVentilator.cpp
+++ b/src/model/ZoneHVACUnitVentilator.cpp
@@ -45,6 +45,7 @@
 #include <utilities/idd/OS_ZoneHVAC_UnitVentilator_FieldEnums.hxx>
 
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -491,6 +492,50 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACUnitVentilator_Impl::componentType() const {
+      const bool has_cooling = coolingCoil().is_initialized();
+      const bool has_heating = heatingCoil().is_initialized();
+
+      if (has_cooling && has_heating) {
+        return ComponentType::Both;
+      } else if (has_cooling) {
+        return ComponentType::Cooling;
+      } else if (has_heating) {
+        return ComponentType::Heating;
+      }
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneHVACUnitVentilator_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto cc_ = coolingCoil()) {
+        for (auto ft : cc_->coolingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACUnitVentilator_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->heatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACUnitVentilator_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      if (auto hc_ = heatingCoil()) {
+        for (auto ft : hc_->appGHeatingFuelTypes()) {
+          result.insert(ft);
+        }
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACUnitVentilator::ZoneHVACUnitVentilator(const Model& model) : ZoneHVACComponent(ZoneHVACUnitVentilator::iddObjectType(), model) {
diff --git a/src/model/ZoneHVACUnitVentilator_Impl.hpp b/src/model/ZoneHVACUnitVentilator_Impl.hpp
index a22602e264d..31bebef331a 100644
--- a/src/model/ZoneHVACUnitVentilator_Impl.hpp
+++ b/src/model/ZoneHVACUnitVentilator_Impl.hpp
@@ -76,6 +76,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneHVACWaterToAirHeatPump.cpp b/src/model/ZoneHVACWaterToAirHeatPump.cpp
index e131f8c8b46..523250f0df3 100644
--- a/src/model/ZoneHVACWaterToAirHeatPump.cpp
+++ b/src/model/ZoneHVACWaterToAirHeatPump.cpp
@@ -57,9 +57,8 @@
 #include <utilities/idd/OS_ZoneHVAC_WaterToAirHeatPump_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
 
-#include "../utilities/units/Unit.hpp"
-
 #include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
 
 namespace openstudio {
 namespace model {
@@ -910,6 +909,40 @@ namespace model {
       }
     }
 
+    ComponentType ZoneHVACWaterToAirHeatPump_Impl::componentType() const {
+      return ComponentType::Both;
+    }
+
+    std::vector<FuelType> ZoneHVACWaterToAirHeatPump_Impl::coolingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : coolingCoil().coolingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<FuelType> ZoneHVACWaterToAirHeatPump_Impl::heatingFuelTypes() const {
+      std::set<FuelType> result;
+      for (auto ft : heatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().heatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
+    std::vector<AppGFuelType> ZoneHVACWaterToAirHeatPump_Impl::appGHeatingFuelTypes() const {
+      std::set<AppGFuelType> result;
+      for (auto ft : heatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      for (auto ft : supplementalHeatingCoil().appGHeatingFuelTypes()) {
+        result.insert(ft);
+      }
+      return {result.begin(), result.end()};
+    }
+
   }  // namespace detail
 
   ZoneHVACWaterToAirHeatPump::ZoneHVACWaterToAirHeatPump(const Model& model, Schedule& availabilitySchedule, HVACComponent& supplyAirFan,
diff --git a/src/model/ZoneHVACWaterToAirHeatPump_Impl.hpp b/src/model/ZoneHVACWaterToAirHeatPump_Impl.hpp
index c2cabc0afc8..0c251ee1ab9 100644
--- a/src/model/ZoneHVACWaterToAirHeatPump_Impl.hpp
+++ b/src/model/ZoneHVACWaterToAirHeatPump_Impl.hpp
@@ -78,6 +78,11 @@ namespace model {
 
       virtual unsigned outletPort() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneVentilationDesignFlowRate.cpp b/src/model/ZoneVentilationDesignFlowRate.cpp
index 101ce5d4208..1460bddd291 100644
--- a/src/model/ZoneVentilationDesignFlowRate.cpp
+++ b/src/model/ZoneVentilationDesignFlowRate.cpp
@@ -40,11 +40,12 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_ZoneVentilation_DesignFlowRate_FieldEnums.hxx>
-#include "../utilities/units/Unit.hpp"
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -530,6 +531,23 @@ namespace model {
       std::vector<std::string> types;
       return types;
     }
+
+    ComponentType ZoneVentilationDesignFlowRate_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneVentilationDesignFlowRate_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneVentilationDesignFlowRate_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ZoneVentilationDesignFlowRate_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ZoneVentilationDesignFlowRate::ZoneVentilationDesignFlowRate(const Model& model)
diff --git a/src/model/ZoneVentilationDesignFlowRate_Impl.hpp b/src/model/ZoneVentilationDesignFlowRate_Impl.hpp
index 700c4937c4f..9b8e5c9150d 100644
--- a/src/model/ZoneVentilationDesignFlowRate_Impl.hpp
+++ b/src/model/ZoneVentilationDesignFlowRate_Impl.hpp
@@ -65,6 +65,11 @@ namespace model {
 
       virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/model/ZoneVentilationWindandStackOpenArea.cpp b/src/model/ZoneVentilationWindandStackOpenArea.cpp
index d03d78c96c7..e3e95ea5cc9 100644
--- a/src/model/ZoneVentilationWindandStackOpenArea.cpp
+++ b/src/model/ZoneVentilationWindandStackOpenArea.cpp
@@ -40,10 +40,12 @@
 #include "ScheduleTypeLimits.hpp"
 #include "ScheduleTypeRegistry.hpp"
 
+#include "../utilities/core/Assert.hpp"
+#include "../utilities/data/DataEnums.hpp"
+
 #include <utilities/idd/IddFactory.hxx>
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_ZoneVentilation_WindandStackOpenArea_FieldEnums.hxx>
-#include "../utilities/core/Assert.hpp"
 
 namespace openstudio {
 namespace model {
@@ -425,6 +427,23 @@ namespace model {
       std::vector<std::string> types;
       return types;
     }
+
+    ComponentType ZoneVentilationWindandStackOpenArea_Impl::componentType() const {
+      return ComponentType::None;
+    }
+
+    std::vector<FuelType> ZoneVentilationWindandStackOpenArea_Impl::coolingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<FuelType> ZoneVentilationWindandStackOpenArea_Impl::heatingFuelTypes() const {
+      return {};
+    }
+
+    std::vector<AppGFuelType> ZoneVentilationWindandStackOpenArea_Impl::appGHeatingFuelTypes() const {
+      return {};
+    }
+
   }  // namespace detail
 
   ZoneVentilationWindandStackOpenArea::ZoneVentilationWindandStackOpenArea(const Model& model)
diff --git a/src/model/ZoneVentilationWindandStackOpenArea_Impl.hpp b/src/model/ZoneVentilationWindandStackOpenArea_Impl.hpp
index 69ad3c6476e..f8671fa597f 100644
--- a/src/model/ZoneVentilationWindandStackOpenArea_Impl.hpp
+++ b/src/model/ZoneVentilationWindandStackOpenArea_Impl.hpp
@@ -79,6 +79,11 @@ namespace model {
 
       virtual std::vector<std::string> emsInternalVariableNames() const override;
 
+      virtual ComponentType componentType() const override;
+      virtual std::vector<FuelType> coolingFuelTypes() const override;
+      virtual std::vector<FuelType> heatingFuelTypes() const override;
+      virtual std::vector<AppGFuelType> appGHeatingFuelTypes() const override;
+
       //@}
       /** @name Getters */
       //@{
diff --git a/src/sdd/ReverseTranslator.cpp b/src/sdd/ReverseTranslator.cpp
index 33bdbf9796c..a40134ed856 100644
--- a/src/sdd/ReverseTranslator.cpp
+++ b/src/sdd/ReverseTranslator.cpp
@@ -818,8 +818,9 @@ namespace sdd {
 
       if (fuelType == FuelType::Gasoline || fuelType == FuelType::Diesel || fuelType == FuelType::FuelOil_1 || fuelType == FuelType::FuelOil_2
           || fuelType == FuelType::Propane || fuelType == FuelType::Water || fuelType == FuelType::Steam || fuelType == FuelType::OtherFuel_1
-          || fuelType == FuelType::OtherFuel_2 || fuelType == FuelType::EnergyTransfer) {
-        // TODO: why are we ignoring these?! Aside from EnergyTransfer at least
+          || fuelType == FuelType::OtherFuel_2 || fuelType == FuelType::EnergyTransfer || fuelType == FuelType::Geothermal
+          || fuelType == FuelType::Solar) {
+        // TODO: why are we ignoring these?! Aside from EnergyTransfer, Solar and Geothermal at least
         // skip these to avoid E+ warning, EnergyTransfer is internal to the simulation
         continue;
       }
diff --git a/src/utilities/data/Data.i b/src/utilities/data/Data.i
index d130c245d3e..348095d4fab 100644
--- a/src/utilities/data/Data.i
+++ b/src/utilities/data/Data.i
@@ -33,6 +33,10 @@
 %template(OptionalEndUseType) boost::optional<openstudio::EndUseType>;
 %template(BuildingSectorVector) std::vector<openstudio::BuildingSector>;
 %template(OptionalBuildingSector) boost::optional<openstudio::BuildingSector>;
+%template(AppGFuelTypeVector) std::vector<openstudio::AppGFuelType>;
+%template(OptionalAppGFuelType) boost::optional<openstudio::AppGFuelType>;
+%template(ComponentTypeVector) std::vector<openstudio::ComponentType>;
+%template(OptionalComponentType) boost::optional<openstudio::ComponentType>;
 
 %include <utilities/data/DataEnums.hpp>
 %include <utilities/data/Attribute.i>
diff --git a/src/utilities/data/DataEnums.hpp b/src/utilities/data/DataEnums.hpp
index 54b8cc86ad7..897f91feb2c 100644
--- a/src/utilities/data/DataEnums.hpp
+++ b/src/utilities/data/DataEnums.hpp
@@ -81,6 +81,8 @@ OPENSTUDIO_ENUM(FuelType,
   ((OtherFuel_1)(OtherFuel1))
   ((OtherFuel_2)(OtherFuel2))
   ((EnergyTransfer))
+  ((Solar))
+  ((Geothermal))
 );
  *  \endcode */
 OPENSTUDIO_ENUM(FuelType,
@@ -99,6 +101,8 @@ OPENSTUDIO_ENUM(FuelType,
   ((OtherFuel_1)(OtherFuel1))
   ((OtherFuel_2)(OtherFuel2))
   ((EnergyTransfer))
+  ((Solar))
+  ((Geothermal))
 );
 
 /** \relates FuelType */
@@ -249,8 +253,84 @@ OPENSTUDIO_ENUM(BuildingSector,
   ((Residential))
 );
 
+
+
+
+/** \class AppGFuelType
+ *  \brief heat for coil for Appendix G system type selections
+ *  \details See the OPENSTUDIO_ENUM documentation in utilities/core/Enum.hpp. The actual
+ *  macro call is:
+ *  \code
+OPENSTUDIO_ENUM(AppGFuelType,
+  ((District))
+  ((Electric))
+  ((Fuel))
+  ((HeatPump))
+  ((Other))
+  ((Solar))
+);
+ *  \endcode */
+OPENSTUDIO_ENUM(AppGFuelType,
+  ((District))
+  ((Electric))
+  ((Fuel))
+  ((Geothermal))
+  ((HeatPump))
+  ((Other))
+  ((Solar))
+);
+
+/** \relates AppGFuelType */
+using OptionalAppGFuelType = boost::optional<AppGFuelType>;
+
+/** \relates AppGFuelType */
+using AppGFuelTypeVector = std::vector<AppGFuelType>;
+
+/** \class ComponentType
+ *  \brief What an HVACComponent is meant to do: heating, cooling, both or none
+ *  \details See the OPENSTUDIO_ENUM documentation in utilities/core/Enum.hpp. The actual
+ *  macro call is:
+ *  \code
+ OPENSTUDIO_ENUM(ComponentType,
+  ((Heating))
+  ((Cooling))
+  ((Both))
+  ((None))
+);
+ *  \endcode */
+OPENSTUDIO_ENUM(ComponentType,
+  ((Heating))
+  ((Cooling))
+  ((Both))
+  ((None))
+);
+
+/** \relates ComponentType */
+using OptionalComponentType = boost::optional<ComponentType>;
+
+/** \relates ComponentType */
+using ComponentTypeVector = std::vector<ComponentType>;
+
 // clang-format on
 
+inline UTILITIES_API AppGFuelType convertFuelTypeToAppG(FuelType fuelType) {
+
+  if (fuelType == FuelType::Electricity) {
+    return AppGFuelType::Electric;
+  } else if ((fuelType == FuelType::Gas) || (fuelType == FuelType::Gasoline) || (fuelType == FuelType::Diesel) || (fuelType == FuelType::Coal)
+             || (fuelType == FuelType::FuelOil_1) || (fuelType == FuelType::FuelOil_2) || (fuelType == FuelType::Propane)
+             || (fuelType == FuelType::Steam) || (fuelType == FuelType::OtherFuel_1) || (fuelType == FuelType::OtherFuel_2)) {
+    return AppGFuelType::Fuel;
+  } else if ((fuelType == FuelType::DistrictCooling) || (fuelType == FuelType::DistrictHeating)) {
+    return AppGFuelType::District;
+  }
+
+  // (fuelType == FuelType::Water)
+  // (fuelType == FuelType::EnergyTransfer)
+
+  return AppGFuelType::Other;
+}
+
 }  // namespace openstudio
 
 #endif  // UTILITIES_DATA_DATAENUMS_HPP


Test patch:
diff --git a/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_GTest.cpp b/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_GTest.cpp
index 046c5b4abda..776d50e89c6 100644
--- a/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_GTest.cpp
+++ b/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_GTest.cpp
@@ -390,12 +390,21 @@ TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureContro
   ZoneHVACTerminalUnitVariableRefrigerantFlow term3(model, coolingCoil3, heatingCoil3, fan3);
 
   EXPECT_EQ(0u, vrf.terminals().size());
+  EXPECT_FALSE(term1.vrfSystem());
+  EXPECT_FALSE(term2.vrfSystem());
+  EXPECT_FALSE(term3.vrfSystem());
 
   EXPECT_TRUE(vrf.addTerminal(term1));
   EXPECT_TRUE(vrf.addTerminal(term2));
   EXPECT_TRUE(vrf.addTerminal(term3));
 
   EXPECT_EQ(3u, vrf.terminals().size());
+  ASSERT_TRUE(term1.vrfSystem());
+  EXPECT_EQ(vrf, term1.vrfSystem().get());
+  ASSERT_TRUE(term2.vrfSystem());
+  EXPECT_EQ(vrf, term2.vrfSystem().get());
+  ASSERT_TRUE(term3.vrfSystem());
+  EXPECT_EQ(vrf, term3.vrfSystem().get());
 
   vrf.removeTerminal(term2);
 
@@ -403,9 +412,18 @@ TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureContro
   EXPECT_EQ(term1, vrf.terminals()[0]);
   EXPECT_EQ(term3, vrf.terminals()[1]);
 
+  ASSERT_TRUE(term1.vrfSystem());
+  EXPECT_EQ(vrf, term1.vrfSystem().get());
+  EXPECT_FALSE(term2.vrfSystem());
+  ASSERT_TRUE(term3.vrfSystem());
+  EXPECT_EQ(vrf, term3.vrfSystem().get());
+
   vrf.removeAllTerminals();
 
   EXPECT_EQ(0u, vrf.terminals().size());
+  EXPECT_FALSE(term1.vrfSystem());
+  EXPECT_FALSE(term2.vrfSystem());
+  EXPECT_FALSE(term3.vrfSystem());
 }
 
 TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureControlHR_Clone) {
diff --git a/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_GTest.cpp b/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_GTest.cpp
index ac07d7ddd67..2f372dc15a0 100644
--- a/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_GTest.cpp
+++ b/src/model/test/AirConditionerVariableRefrigerantFlowFluidTemperatureControl_GTest.cpp
@@ -342,11 +342,21 @@ TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureContro
 
   EXPECT_EQ(0u, vrf.terminals().size());
 
+  EXPECT_FALSE(term1.vrfSystem());
+  EXPECT_FALSE(term2.vrfSystem());
+  EXPECT_FALSE(term3.vrfSystem());
+
   EXPECT_TRUE(vrf.addTerminal(term1));
   EXPECT_TRUE(vrf.addTerminal(term2));
   EXPECT_TRUE(vrf.addTerminal(term3));
 
   EXPECT_EQ(3u, vrf.terminals().size());
+  ASSERT_TRUE(term1.vrfSystem());
+  EXPECT_EQ(vrf, term1.vrfSystem().get());
+  ASSERT_TRUE(term2.vrfSystem());
+  EXPECT_EQ(vrf, term2.vrfSystem().get());
+  ASSERT_TRUE(term3.vrfSystem());
+  EXPECT_EQ(vrf, term3.vrfSystem().get());
 
   vrf.removeTerminal(term2);
 
@@ -354,9 +364,18 @@ TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureContro
   EXPECT_EQ(term1, vrf.terminals()[0]);
   EXPECT_EQ(term3, vrf.terminals()[1]);
 
+  ASSERT_TRUE(term1.vrfSystem());
+  EXPECT_EQ(vrf, term1.vrfSystem().get());
+  EXPECT_FALSE(term2.vrfSystem());
+  ASSERT_TRUE(term3.vrfSystem());
+  EXPECT_EQ(vrf, term3.vrfSystem().get());
+
   vrf.removeAllTerminals();
 
   EXPECT_EQ(0u, vrf.terminals().size());
+  EXPECT_FALSE(term1.vrfSystem());
+  EXPECT_FALSE(term2.vrfSystem());
+  EXPECT_FALSE(term3.vrfSystem());
 }
 
 TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlowFluidTemperatureControl_Clone) {
diff --git a/src/model/test/AirConditionerVariableRefrigerantFlow_GTest.cpp b/src/model/test/AirConditionerVariableRefrigerantFlow_GTest.cpp
index f515aa0d460..c295b0b5981 100644
--- a/src/model/test/AirConditionerVariableRefrigerantFlow_GTest.cpp
+++ b/src/model/test/AirConditionerVariableRefrigerantFlow_GTest.cpp
@@ -80,10 +80,13 @@ TEST_F(ModelFixture, AirConditionerVariableRefrigerantFlow) {
     ThermalZone zone(m);
 
     ZoneHVACTerminalUnitVariableRefrigerantFlow vrfTerminal(m);
+    EXPECT_FALSE(vrfTerminal.vrfSystem());
 
     ASSERT_TRUE(vrfTerminal.addToThermalZone(zone));
 
     vrf.addTerminal(vrfTerminal);
+    ASSERT_TRUE(vrfTerminal.vrfSystem());
+    EXPECT_EQ(vrf, vrfTerminal.vrfSystem().get());
   }
 
   ASSERT_EQ(5u, vrf.terminals().size());
diff --git a/src/model/test/BoilerHotWater_GTest.cpp b/src/model/test/BoilerHotWater_GTest.cpp
index 96adb5bb6d2..ca5d8eb84d7 100644
--- a/src/model/test/BoilerHotWater_GTest.cpp
+++ b/src/model/test/BoilerHotWater_GTest.cpp
@@ -36,6 +36,7 @@
 #include "../Node.hpp"
 #include "../Node_Impl.hpp"
 #include "../AirLoopHVACZoneSplitter.hpp"
+#include "../../utilities/data/DataEnums.hpp"
 
 using namespace openstudio::model;
 
@@ -144,3 +145,35 @@ TEST_F(ModelFixture, BoilerHotWater_remove) {
   EXPECT_TRUE(n1.handle().isNull());
   EXPECT_TRUE(n2.handle().isNull());
 }
+
+TEST_F(ModelFixture, BoilerHotWater_HeatCoolFuelTypes) {
+
+  using namespace openstudio;
+
+  Model m;
+
+  PlantLoop p(m);
+  BoilerHotWater b(m);
+  p.addSupplyBranchForComponent(b);
+
+  for (auto& fuelTypeString : BoilerHotWater::validFuelTypeValues()) {
+    EXPECT_TRUE(b.setFuelType(fuelTypeString));
+
+    const FuelType fuelType(fuelTypeString);
+    const AppGFuelType appGFuelType = convertFuelTypeToAppG(fuelType);
+
+    EXPECT_EQ(ComponentType(ComponentType::Heating), b.componentType());
+    EXPECT_EQ(0, b.coolingFuelTypes().size());
+    ASSERT_EQ(1, b.heatingFuelTypes().size());
+    EXPECT_EQ(fuelType, b.heatingFuelTypes().front());
+    ASSERT_EQ(1, b.appGHeatingFuelTypes().size());
+    EXPECT_EQ(appGFuelType, b.appGHeatingFuelTypes().front());
+
+    EXPECT_EQ(ComponentType(ComponentType::Heating), p.componentType());
+    EXPECT_EQ(0, p.coolingFuelTypes().size());
+    ASSERT_EQ(1, p.heatingFuelTypes().size());
+    EXPECT_EQ(fuelType, p.heatingFuelTypes().front());
+    ASSERT_EQ(1, p.appGHeatingFuelTypes().size());
+    EXPECT_EQ(appGFuelType, p.appGHeatingFuelTypes().front());
+  }
+}
diff --git a/src/model/test/ModelFixture.cpp b/src/model/test/ModelFixture.cpp
index 0380f77fa08..91037068145 100644
--- a/src/model/test/ModelFixture.cpp
+++ b/src/model/test/ModelFixture.cpp
@@ -72,5 +72,17 @@ void ModelFixture::testBooleanIddField(const openstudio::IddField& iddField, con
   }
 }
 
+bool ModelFixture::testFuelTypeEquality(const std::vector<openstudio::FuelType>& expectedFuelTypes,
+                                        const std::vector<openstudio::FuelType>& actualFuelTypes) {
+  EXPECT_EQ(expectedFuelTypes, actualFuelTypes);
+  return expectedFuelTypes == actualFuelTypes;
+}
+
+bool ModelFixture::testAppGFuelTypeEquality(const std::vector<openstudio::AppGFuelType>& expectedAppGFuelTypes,
+                                            const std::vector<openstudio::AppGFuelType>& actualAppGFuelTypes) {
+  EXPECT_EQ(expectedAppGFuelTypes, actualAppGFuelTypes);
+  return expectedAppGFuelTypes == actualAppGFuelTypes;
+}
+
 double ModelFixture::tol(1.0E-5);
 boost::optional<openstudio::FileLogSink> ModelFixture::logFile;
diff --git a/src/model/test/ModelFixture.hpp b/src/model/test/ModelFixture.hpp
index 33c20a33850..2d0307798a3 100644
--- a/src/model/test/ModelFixture.hpp
+++ b/src/model/test/ModelFixture.hpp
@@ -40,6 +40,7 @@
 #include "../../utilities/sql/SqlFile.hpp"
 #include "../../utilities/core/Logger.hpp"
 #include "../../utilities/core/FileLogSink.hpp"
+#include "../../utilities/data/DataEnums.hpp"
 
 class ModelFixture : public ::testing::Test
 {
@@ -59,6 +60,11 @@ class ModelFixture : public ::testing::Test
   // test that the given iddField is a boolean Yes/No choice field
   void testBooleanIddField(const openstudio::IddField& iddField, const boost::optional<std::string>& defaultValue);
 
+  bool testFuelTypeEquality(const std::vector<openstudio::FuelType>& expectedFuelTypes, const std::vector<openstudio::FuelType>& actualFuelTypes);
+
+  bool testAppGFuelTypeEquality(const std::vector<openstudio::AppGFuelType>& expectedAppGFuelTypes,
+                                const std::vector<openstudio::AppGFuelType>& actualAppGFuelTypes);
+
   // set up logging
   REGISTER_LOGGER("ModelFixture");
 
diff --git a/src/model/test/OutputMeter_GTest.cpp b/src/model/test/OutputMeter_GTest.cpp
index fbfc03d0963..299adea507f 100644
--- a/src/model/test/OutputMeter_GTest.cpp
+++ b/src/model/test/OutputMeter_GTest.cpp
@@ -367,52 +367,58 @@ TEST_F(ModelFixture, MeterFromModel) {
 TEST_F(ModelFixture, MeterEnumValues) {
   Model model;
 
-  std::set<int> installLocationTypes = InstallLocationType::getValues();
-  for (int installLocationType : installLocationTypes) {
+  const std::set<int> installLocationTypes = InstallLocationType::getValues();
+  for (const InstallLocationType installLocationType : installLocationTypes) {
     OutputMeter meter(model);
-    EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType(installLocationType))) << InstallLocationType(installLocationType).valueName();
-    ASSERT_TRUE(meter.installLocationType()) << InstallLocationType(installLocationType).valueName();
+    EXPECT_TRUE(meter.setInstallLocationType(installLocationType)) << installLocationType.valueName();
+    ASSERT_TRUE(meter.installLocationType()) << installLocationType.valueName();
     EXPECT_EQ(installLocationType, meter.installLocationType().get().value())
-      << InstallLocationType(installLocationType).valueName() << " != " << meter.installLocationType().get().valueName();
+      << installLocationType.valueName() << " != " << meter.installLocationType().get().valueName();
   }
 
   std::set<int> fuelTypes = FuelType::getValues();
-  for (int fuelType : fuelTypes) {
+  for (const FuelType fuelType : fuelTypes) {
     OutputMeter meter(model);
-    EXPECT_TRUE(meter.setFuelType(FuelType(fuelType))) << FuelType(fuelType).valueName();
-    ASSERT_TRUE(meter.fuelType()) << FuelType(fuelType).valueName();
-    EXPECT_EQ(fuelType, meter.fuelType().get().value()) << FuelType(fuelType).valueName() << " != " << meter.fuelType().get().valueName();
+    if (fuelType == FuelType::Geothermal || fuelType == FuelType::Solar) {
+      EXPECT_ANY_THROW(meter.setFuelType(fuelType));
+      continue;
+    }
+    EXPECT_TRUE(meter.setFuelType(fuelType)) << fuelType.valueName();
+    ASSERT_TRUE(meter.fuelType()) << fuelType.valueName();
+    EXPECT_EQ(fuelType, meter.fuelType().get().value()) << fuelType.valueName() << " != " << meter.fuelType().get().valueName();
   }
 
-  std::set<int> endUseTypes = EndUseType::getValues();
-  for (int endUseType : endUseTypes) {
+  fuelTypes.erase(FuelType::Geothermal);
+  fuelTypes.erase(FuelType::Solar);
+
+  const std::set<int> endUseTypes = EndUseType::getValues();
+  for (const EndUseType endUseType : endUseTypes) {
     OutputMeter meter(model);
-    EXPECT_TRUE(meter.setEndUseType(EndUseType(endUseType))) << EndUseType(endUseType).valueName();
-    ASSERT_TRUE(meter.endUseType()) << EndUseType(endUseType).valueName();
-    EXPECT_EQ(endUseType, meter.endUseType().get().value()) << EndUseType(endUseType).valueName() << " != " << meter.endUseType().get().valueName();
+    EXPECT_TRUE(meter.setEndUseType(endUseType)) << endUseType.valueName();
+    ASSERT_TRUE(meter.endUseType()) << endUseType.valueName();
+    EXPECT_EQ(endUseType, meter.endUseType().get().value()) << endUseType.valueName() << " != " << meter.endUseType().get().valueName();
   }
 
-  for (int installLocationType : installLocationTypes) {
-    for (int fuelType : fuelTypes) {
-      for (int endUseType : endUseTypes) {
+  for (const InstallLocationType installLocationType : installLocationTypes) {
+    for (const FuelType fuelType : fuelTypes) {
+      for (const EndUseType endUseType : endUseTypes) {
         OutputMeter meter(model);
-        EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType(installLocationType))) << InstallLocationType(installLocationType).valueName();
-        EXPECT_TRUE(meter.setFuelType(FuelType(fuelType))) << FuelType(fuelType).valueName();
-        EXPECT_TRUE(meter.setEndUseType(EndUseType(endUseType))) << EndUseType(endUseType).valueName();
+        EXPECT_TRUE(meter.setInstallLocationType(installLocationType)) << installLocationType.valueName();
+        EXPECT_TRUE(meter.setFuelType(fuelType)) << fuelType.valueName();
+        EXPECT_TRUE(meter.setEndUseType(endUseType)) << endUseType.valueName();
 
         // this is a specific case handled by OutputMeter
         if (installLocationType != InstallLocationType::Facility) {
-          ASSERT_TRUE(meter.installLocationType()) << InstallLocationType(installLocationType).valueName();
+          ASSERT_TRUE(meter.installLocationType()) << installLocationType.valueName();
           EXPECT_EQ(installLocationType, meter.installLocationType().get().value())
-            << InstallLocationType(installLocationType).valueName() << " != " << meter.installLocationType().get().valueName();
+            << installLocationType.valueName() << " != " << meter.installLocationType().get().valueName();
         }
 
-        ASSERT_TRUE(meter.fuelType()) << FuelType(fuelType).valueName();
-        EXPECT_EQ(fuelType, meter.fuelType().get().value()) << FuelType(fuelType).valueName() << " != " << meter.fuelType().get().valueName();
+        ASSERT_TRUE(meter.fuelType()) << fuelType.valueName();
+        EXPECT_EQ(fuelType, meter.fuelType().get().value()) << fuelType.valueName() << " != " << meter.fuelType().get().valueName();
 
-        ASSERT_TRUE(meter.endUseType()) << EndUseType(endUseType).valueName();
-        EXPECT_EQ(endUseType, meter.endUseType().get().value())
-          << EndUseType(endUseType).valueName() << " != " << meter.endUseType().get().valueName();
+        ASSERT_TRUE(meter.endUseType()) << endUseType.valueName();
+        EXPECT_EQ(endUseType, meter.endUseType().get().value()) << endUseType.valueName() << " != " << meter.endUseType().get().valueName();
       }
     }
   }
diff --git a/src/model/test/ThermalZone_GTest.cpp b/src/model/test/ThermalZone_GTest.cpp
index 52082b56753..f3ca4706f3a 100644
--- a/src/model/test/ThermalZone_GTest.cpp
+++ b/src/model/test/ThermalZone_GTest.cpp
@@ -31,11 +31,15 @@
 
 #include "ModelFixture.hpp"
 
+#include "../AirConditionerVariableRefrigerantFlow.hpp"
 #include "../AirLoopHVAC.hpp"
 #include "../AirLoopHVACZoneSplitter.hpp"
 #include "../AirLoopHVACZoneMixer.hpp"
 #include "../AirTerminalSingleDuctConstantVolumeNoReheat.hpp"
+#include "../BoilerHotWater.hpp"
+#include "../CoolingTowerSingleSpeed.hpp"
 #include "../CoilCoolingDXSingleSpeed.hpp"
+#include "../CoilHeatingDXSingleSpeed.hpp"
 #include "../CoilHeatingWater.hpp"
 #include "../CurveBiquadratic.hpp"
 #include "../CurveQuadratic.hpp"
@@ -49,6 +53,7 @@
 #include "../Model_Impl.hpp"
 #include "../Node.hpp"
 #include "../Node_Impl.hpp"
+#include "../PlantLoop.hpp"
 #include "../PortList.hpp"
 #include "../PortList_Impl.hpp"
 #include "../ScheduleCompact.hpp"
@@ -72,8 +77,8 @@
 #include "../ZoneControlContaminantController.hpp"
 #include "../ZoneControlContaminantController_Impl.hpp"
 #include "../ZoneHVACPackagedTerminalAirConditioner.hpp"
-
-#include "../ScheduleConstant.hpp"
+#include "../ZoneHVACPackagedTerminalHeatPump.hpp"
+#include "../ZoneHVACTerminalUnitVariableRefrigerantFlow.hpp"
 #include "../ZoneHVACUnitHeater.hpp"
 #include "../ZoneHVACUnitHeater_Impl.hpp"
 
@@ -818,3 +823,110 @@ TEST_F(ModelFixture, ThermalZone_DaylightingControlsAvailabilitySchedule) {
   z.resetDaylightingControlsAvailabilitySchedule();
   EXPECT_FALSE(z.daylightingControlsAvailabilitySchedule());
 }
+
+TEST_F(ModelFixture, ThermalZone_HeatCoolFuelTypes) {
+
+  Model m;
+
+  FanConstantVolume fan(m);
+  CoilHeatingDXSingleSpeed hc(m);
+  CoilCoolingDXSingleSpeed cc(m);
+  CoilHeatingWater supHC(m);
+  auto alwaysOn = m.alwaysOnDiscreteSchedule();
+  ZoneHVACPackagedTerminalHeatPump pthp(m, alwaysOn, fan, hc, cc, supHC);
+
+  PlantLoop pthpPlantLoop(m);
+  BoilerHotWater b(m);
+  EXPECT_TRUE(b.setFuelType("Propane"));
+  EXPECT_TRUE(pthpPlantLoop.addSupplyBranchForComponent(b));
+  EXPECT_TRUE(pthpPlantLoop.addDemandBranchForComponent(supHC));
+
+  PlantLoop vrfPlantLoop(m);
+  CoolingTowerSingleSpeed ct(m);
+  AirConditionerVariableRefrigerantFlow vrfSystem(m);
+  EXPECT_TRUE(vrfSystem.setFuelType("NaturalGas"));
+  EXPECT_TRUE(vrfPlantLoop.addSupplyBranchForComponent(ct));
+  EXPECT_TRUE(vrfPlantLoop.addDemandBranchForComponent(vrfSystem));
+  EXPECT_EQ("WaterCooled", vrfSystem.condenserType());
+
+  ZoneHVACTerminalUnitVariableRefrigerantFlow vrfTerminal(m, false);
+  EXPECT_TRUE(vrfSystem.addTerminal(vrfTerminal));
+
+  ThermalZone z(m);
+  EXPECT_TRUE(vrfTerminal.addToThermalZone(z));
+  EXPECT_TRUE(pthp.addToThermalZone(z));
+
+  EXPECT_EQ(2, z.equipment().size());
+
+  // VRF Terminal
+  {
+    // VRF PlantLoop: it has only the Cooling tower
+    EXPECT_EQ(ComponentType(ComponentType::Cooling), ct.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity}, ct.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({}, ct.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({}, ct.appGHeatingFuelTypes()));
+
+    EXPECT_EQ(ComponentType(ComponentType::Cooling), vrfPlantLoop.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity}, vrfPlantLoop.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({}, vrfPlantLoop.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({}, vrfPlantLoop.appGHeatingFuelTypes()));
+
+    // VRFSystem: this is the fuelType + the PlantLoop if any
+    EXPECT_EQ(ComponentType(ComponentType::Both), vrfSystem.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Gas}, vrfSystem.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Gas}, vrfSystem.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel}, vrfSystem.appGHeatingFuelTypes()));
+
+    // vrfTerminal should return Electric/HeatPump + whatever its VRFSystem is doing
+    EXPECT_EQ(ComponentType(ComponentType::Both), vrfTerminal.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Gas}, vrfTerminal.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Gas}, vrfTerminal.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, vrfTerminal.appGHeatingFuelTypes()));
+  }
+
+  // PTHP
+  {
+    // Cooling Coil
+    EXPECT_EQ(ComponentType(ComponentType::Cooling), cc.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity}, cc.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({}, cc.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({}, cc.appGHeatingFuelTypes()));
+
+    // Heating Coil
+    EXPECT_EQ(ComponentType(ComponentType::Heating), hc.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({}, hc.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity}, hc.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::HeatPump}, hc.appGHeatingFuelTypes()));
+
+    // Supplemental Heating Coil: this is a CoilHeatingWater to it grabs the plantloop
+    {
+      // Boiler is Propane
+      EXPECT_EQ(ComponentType(ComponentType::Heating), b.componentType());
+      EXPECT_TRUE(testFuelTypeEquality({}, b.coolingFuelTypes()));
+      EXPECT_TRUE(testFuelTypeEquality({FuelType::Propane}, b.heatingFuelTypes()));
+      EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel}, b.appGHeatingFuelTypes()));
+
+      EXPECT_EQ(ComponentType(ComponentType::Heating), pthpPlantLoop.componentType());
+      EXPECT_TRUE(testFuelTypeEquality({}, pthpPlantLoop.coolingFuelTypes()));
+      EXPECT_TRUE(testFuelTypeEquality({FuelType::Propane}, pthpPlantLoop.heatingFuelTypes()));
+      EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel}, pthpPlantLoop.appGHeatingFuelTypes()));
+
+      EXPECT_EQ(ComponentType(ComponentType::Heating), supHC.componentType());
+      EXPECT_TRUE(testFuelTypeEquality({}, supHC.coolingFuelTypes()));
+      EXPECT_TRUE(testFuelTypeEquality({FuelType::Propane}, supHC.heatingFuelTypes()));
+      EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel}, supHC.appGHeatingFuelTypes()));
+    }
+
+    // PTHP is the sum of Cooling + Heating + supHC coils
+    EXPECT_EQ(ComponentType(ComponentType::Both), pthp.componentType());
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity}, pthp.coolingFuelTypes()));
+    EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Propane}, pthp.heatingFuelTypes()));
+    EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, pthp.appGHeatingFuelTypes()));
+  }
+
+  // Zone checks the zone equipment
+  EXPECT_EQ(ComponentType(ComponentType::Both), z.componentType());
+  EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Gas}, z.coolingFuelTypes()));
+  EXPECT_TRUE(testFuelTypeEquality({FuelType::Electricity, FuelType::Gas, FuelType::Propane}, z.heatingFuelTypes()));
+  EXPECT_TRUE(testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, z.appGHeatingFuelTypes()));
+}
diff --git a/src/model/test/UtilityBill_GTest.cpp b/src/model/test/UtilityBill_GTest.cpp
index 3be2b8aad8d..2d6673cd9be 100644
--- a/src/model/test/UtilityBill_GTest.cpp
+++ b/src/model/test/UtilityBill_GTest.cpp
@@ -239,7 +239,12 @@ TEST_F(ModelFixture, UtilityBill_Electricity_Issue765) {
 TEST_F(ModelFixture, UtilityBill_Coverage) {
   Model model;
 
-  for (FuelType fuelType : FuelType::getValues()) {
+  for (const FuelType fuelType : FuelType::getValues()) {
+
+    if (fuelType == FuelType::Geothermal || fuelType == FuelType::Solar) {
+      EXPECT_ANY_THROW(UtilityBill(fuelType, model));
+      continue;
+    }
 
     UtilityBill utilityBill(fuelType, model);
     EXPECT_EQ(fuelType, utilityBill.fuelType().value());
diff --git a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp
index 9ed7344e29a..e70c3e3794c 100644
--- a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp
+++ b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp
@@ -42,6 +42,8 @@
 #include "../Schedule.hpp"
 #include "../ScheduleConstant.hpp"
 #include "../WaterHeaterStratified.hpp"
+#include "../WaterHeaterStratified_Impl.hpp"
+#include "../PlantLoop.hpp"
 
 using namespace openstudio;
 using namespace openstudio::model;
@@ -235,3 +237,46 @@ TEST_F(ModelFixture, WaterHeaterHeatPumpWrappedCondenser_GettersSetters) {
   ASSERT_TRUE(hpwh.controlSensor2HeightInStratifiedTank());
   EXPECT_EQ(0.1, hpwh.controlSensor2HeightInStratifiedTank().get());
 }
+
+TEST_F(ModelFixture, WaterHeaterHeatPumpWrappedCondenser_HeatCoolFuelTypes) {
+  // Test for #4053
+  Model m;
+  WaterHeaterHeatPumpWrappedCondenser hpwh(m);
+  auto tank = hpwh.tank().cast<WaterHeaterStratified>();
+
+  ThermalZone zone(m);
+  EXPECT_TRUE(hpwh.addToThermalZone(zone));
+
+  PlantLoop plantLoop(m);
+  EXPECT_TRUE(plantLoop.addSupplyBranchForComponent(tank));
+
+  // Tank has no heater capacity, so it should only return the HPWH's
+  EXPECT_TRUE(tank.setHeaterFuelType("NaturalGas"));
+  EXPECT_TRUE(tank.setHeater1Capacity(0.0));
+  EXPECT_TRUE(tank.setHeater2Capacity(0.0));
+  EXPECT_EQ(ComponentType(ComponentType::Heating), tank.componentType());
+  EXPECT_EQ(0, tank.coolingFuelTypes().size());
+  ASSERT_EQ(1, tank.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), tank.heatingFuelTypes().front());
+  ASSERT_EQ(1, tank.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::HeatPump), tank.appGHeatingFuelTypes().front());
+
+  // HPWH should not affect the zone
+  EXPECT_EQ(ComponentType(ComponentType::None), zone.componentType());
+  EXPECT_EQ(0, zone.coolingFuelTypes().size());
+  EXPECT_EQ(0, zone.heatingFuelTypes().size());
+  EXPECT_EQ(0, zone.appGHeatingFuelTypes().size());
+  // And that's because we set the HPWH to be none/empty
+  EXPECT_EQ(ComponentType(ComponentType::None), hpwh.componentType());
+  EXPECT_EQ(0, hpwh.coolingFuelTypes().size());
+  EXPECT_EQ(0, hpwh.heatingFuelTypes().size());
+  EXPECT_EQ(0, hpwh.appGHeatingFuelTypes().size());
+
+  // But the tank should affect the plantLoop
+  EXPECT_EQ(ComponentType(ComponentType::Heating), plantLoop.componentType());
+  EXPECT_EQ(0, plantLoop.coolingFuelTypes().size());
+  ASSERT_EQ(1, plantLoop.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), plantLoop.heatingFuelTypes().front());
+  ASSERT_EQ(1, plantLoop.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::HeatPump), plantLoop.appGHeatingFuelTypes().front());
+}
diff --git a/src/model/test/WaterHeaterHeatPump_GTest.cpp b/src/model/test/WaterHeaterHeatPump_GTest.cpp
index 23f54af7747..887cb3e8db7 100644
--- a/src/model/test/WaterHeaterHeatPump_GTest.cpp
+++ b/src/model/test/WaterHeaterHeatPump_GTest.cpp
@@ -42,6 +42,8 @@
 #include "../Schedule.hpp"
 #include "../ScheduleConstant.hpp"
 #include "../WaterHeaterMixed.hpp"
+#include "../WaterHeaterMixed_Impl.hpp"
+#include "../PlantLoop.hpp"
 
 using namespace openstudio;
 using namespace openstudio::model;
@@ -294,3 +296,45 @@ TEST_F(ModelFixture, WaterHeaterHeatPump_InletAirTemperatureforCompressorOperati
   EXPECT_EQ(-10.0, hpwh.minimumInletAirTemperatureforCompressorOperation());
   EXPECT_EQ(40.0, hpwh.maximumInletAirTemperatureforCompressorOperation());
 }
+
+TEST_F(ModelFixture, WaterHeaterHeatPump_HeatCoolFuelTypes) {
+  // Test for #4053
+  Model m;
+  WaterHeaterHeatPump hpwh(m);
+  auto tank = hpwh.tank().cast<WaterHeaterMixed>();
+
+  ThermalZone zone(m);
+  EXPECT_TRUE(hpwh.addToThermalZone(zone));
+
+  PlantLoop plantLoop(m);
+  EXPECT_TRUE(plantLoop.addSupplyBranchForComponent(tank));
+
+  // Tank has no heater capacity, so it should only return the HPWH's
+  EXPECT_TRUE(tank.setHeaterFuelType("NaturalGas"));
+  EXPECT_TRUE(tank.setHeaterMaximumCapacity(0.0));
+  EXPECT_EQ(ComponentType(ComponentType::Heating), tank.componentType());
+  EXPECT_EQ(0, tank.coolingFuelTypes().size());
+  ASSERT_EQ(1, tank.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), tank.heatingFuelTypes().front());
+  ASSERT_EQ(1, tank.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::HeatPump), tank.appGHeatingFuelTypes().front());
+
+  // HPWH should not affect the zone
+  EXPECT_EQ(ComponentType(ComponentType::None), zone.componentType());
+  EXPECT_EQ(0, zone.coolingFuelTypes().size());
+  EXPECT_EQ(0, zone.heatingFuelTypes().size());
+  EXPECT_EQ(0, zone.appGHeatingFuelTypes().size());
+  // And that's because we set the HPWH to be none/empty
+  EXPECT_EQ(ComponentType(ComponentType::None), hpwh.componentType());
+  EXPECT_EQ(0, hpwh.coolingFuelTypes().size());
+  EXPECT_EQ(0, hpwh.heatingFuelTypes().size());
+  EXPECT_EQ(0, hpwh.appGHeatingFuelTypes().size());
+
+  // But the tank should affect the plantLoop
+  EXPECT_EQ(ComponentType(ComponentType::Heating), plantLoop.componentType());
+  EXPECT_EQ(0, plantLoop.coolingFuelTypes().size());
+  ASSERT_EQ(1, plantLoop.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), plantLoop.heatingFuelTypes().front());
+  ASSERT_EQ(1, plantLoop.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::HeatPump), plantLoop.appGHeatingFuelTypes().front());
+}
diff --git a/src/model/test/ZoneHVACPackagedTerminalHeatPump_GTest.cpp b/src/model/test/ZoneHVACPackagedTerminalHeatPump_GTest.cpp
index 685aacd1294..375fde15a86 100644
--- a/src/model/test/ZoneHVACPackagedTerminalHeatPump_GTest.cpp
+++ b/src/model/test/ZoneHVACPackagedTerminalHeatPump_GTest.cpp
@@ -30,6 +30,9 @@
 #include <gtest/gtest.h>
 #include "ModelFixture.hpp"
 
+#include "../ZoneHVACPackagedTerminalHeatPump.hpp"
+#include "../ZoneHVACPackagedTerminalHeatPump_Impl.hpp"
+
 #include "../AirLoopHVAC.hpp"
 #include "../Model.hpp"
 #include "../Node.hpp"
@@ -42,6 +45,7 @@
 #include "../FanConstantVolume_Impl.hpp"
 #include "../CoilHeatingElectric.hpp"
 #include "../CoilHeatingElectric_Impl.hpp"
+#include "../CoilHeatingWater.hpp"
 #include "../CoilCoolingDXSingleSpeed.hpp"
 #include "../CoilCoolingDXSingleSpeed_Impl.hpp"
 #include "../CoilCoolingDXVariableSpeed.hpp"
@@ -52,11 +56,12 @@
 #include "../CoilHeatingDXSingleSpeed_Impl.hpp"
 #include "../CoilHeatingDXVariableSpeed.hpp"
 #include "../CoilHeatingDXVariableSpeed_Impl.hpp"
-#include "../ZoneHVACPackagedTerminalHeatPump.hpp"
-#include "../ZoneHVACPackagedTerminalHeatPump_Impl.hpp"
 #include "../ScheduleCompact.hpp"
 #include "../FanOnOff.hpp"
 #include "../FanSystemModel.hpp"
+#include "../ThermalZone.hpp"
+#include "../PlantLoop.hpp"
+#include "../BoilerHotWater.hpp"
 
 #include <utilities/idd/OS_Curve_Biquadratic_FieldEnums.hxx>
 
@@ -334,3 +339,69 @@ TEST_F(ModelFixture, ZoneHVACPackagedTerminalHeatPump_SupplyAirFanOpSch) {
   model::ZoneHVACPackagedTerminalHeatPump pthpOnOff(m, alwaysOn, fanOnOff, heatingCoil, coolingCoil, supplementalHeatingCoil);
   EXPECT_EQ(alwaysOff, pthpOnOff.supplyAirFanOperatingModeSchedule());
 }
+
+TEST_F(ModelFixture, ZoneHVACPackagedTerminalHeatPump_HeatCoolFuelTypes) {
+
+  Model m;
+
+  FanSystemModel fan(m);
+  CoilHeatingDXVariableSpeed hc(m);
+  CoilCoolingDXVariableSpeed cc(m);
+  CoilHeatingWater supHC(m);
+
+  auto alwaysOn = m.alwaysOnDiscreteSchedule();
+
+  ZoneHVACPackagedTerminalHeatPump pthp(m, alwaysOn, fan, hc, cc, supHC);
+
+  ThermalZone z(m);
+  EXPECT_EQ(ComponentType(ComponentType::None), z.componentType());
+  EXPECT_EQ(0, z.coolingFuelTypes().size());
+  EXPECT_EQ(0, z.heatingFuelTypes().size());
+  EXPECT_EQ(0, z.appGHeatingFuelTypes().size());
+
+  PlantLoop p(m);
+  EXPECT_EQ(0, supHC.heatingFuelTypes().size());
+  EXPECT_EQ(0, p.heatingFuelTypes().size());
+
+  BoilerHotWater b(m);
+  EXPECT_TRUE(p.addSupplyBranchForComponent(b));
+  EXPECT_TRUE(p.addDemandBranchForComponent(supHC));
+
+  EXPECT_TRUE(b.setFuelType("Propane"));
+  ASSERT_EQ(1, b.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Propane), b.heatingFuelTypes().front());
+  ASSERT_EQ(1, p.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Propane), p.heatingFuelTypes().front());
+
+  EXPECT_EQ(ComponentType(ComponentType::Heating), supHC.componentType());
+  EXPECT_EQ(0, supHC.coolingFuelTypes().size());
+  ASSERT_EQ(1, supHC.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Propane), supHC.heatingFuelTypes().front());
+  ASSERT_EQ(1, supHC.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::Fuel), supHC.appGHeatingFuelTypes().front());
+
+  EXPECT_EQ(ComponentType(ComponentType::Cooling), cc.componentType());
+  ASSERT_EQ(1, cc.coolingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), cc.coolingFuelTypes().front());
+  EXPECT_EQ(0, cc.heatingFuelTypes().size());
+  EXPECT_EQ(0, cc.appGHeatingFuelTypes().size());
+
+  EXPECT_EQ(ComponentType(ComponentType::Heating), hc.componentType());
+  EXPECT_EQ(0, hc.coolingFuelTypes().size());
+  ASSERT_EQ(1, hc.heatingFuelTypes().size());
+  EXPECT_EQ(FuelType(FuelType::Electricity), hc.heatingFuelTypes().front());
+  ASSERT_EQ(1, hc.appGHeatingFuelTypes().size());
+  EXPECT_EQ(AppGFuelType(AppGFuelType::HeatPump), hc.appGHeatingFuelTypes().front());
+
+  EXPECT_EQ(ComponentType(ComponentType::Both), pthp.componentType());
+  testFuelTypeEquality({FuelType::Electricity}, pthp.coolingFuelTypes());
+  testFuelTypeEquality({FuelType::Electricity, FuelType::Propane}, pthp.heatingFuelTypes());
+  testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, pthp.appGHeatingFuelTypes());
+
+  EXPECT_TRUE(pthp.addToThermalZone(z));
+
+  EXPECT_EQ(ComponentType(ComponentType::Both), z.componentType());
+  testFuelTypeEquality({FuelType::Electricity}, z.coolingFuelTypes());
+  testFuelTypeEquality({FuelType::Electricity, FuelType::Propane}, z.heatingFuelTypes());
+  testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, z.appGHeatingFuelTypes());
+}