Portfolio Analytics

Endpoints

All Portfolio Analytics

List:
/api/v1/portfolios/{ portfolio ID}/analytics/
Detail:
/api/v1/portfolios/{ portfolio ID}/analytics/{ portfolio analytics ID }
Generate:
/api/v1/portfolios/{ portfolio ID}/analytics/{ portfolio analytics ID }/generate/

Creating Portfolio Analytics

Once you've created a portfolio with building(s) and added sufficient utility bills to each building, you're ready to generate portfolio analytics for that portfolio via the API.

IMPORTANT NOTE:

Data for the portfolio analytics and the portfolio building analytics contained therein is immutable. In other words, you cannot update them after they're created. If you want to change a property or use a different set of buildings, please delete the existing portfolio analytics (if you no longer need it) and create a new one.

Furthermore, if you modify or delete a building in a portfolio that is referenced in a portfolio analytics, the portfolio analytics will be marked INVALID as the underlying building information has changed.

Getting portfolio analytics data is a two part process:

  1. Creating a new portfolio analytics object, including the buildings you want included.
  2. Generating the portfolio analytics results, including results for each building included in the portfolio analytics.

Creating a New Portfolio Analytics

Important: For portfolio analytics, you have two options for benchmark_data_type. If you want to use the default benchmark statistics, use DEFAULT. Currently, reference statistics are only available for the following countries and space types in the table below. Alternatively, if your building space type is not in the table, or you want to generate benchmark statistics using your own buildings' data, you can use GENERATE. Note that at least 30 to 50 buildings in a portfolio is recommended to generate robust benchmark statistics.
Country Space Type
Unites States Office
K-12 School
Multifamily
Public Library
Mexico Office
Tunisia Hotel

To create portfolio analytics, you must POST four pieces of information in JSON form to a particular portfolio's analytics endpoint, using that portfolios's ID (e.g. /api/v1/portfolios/23/analytics/).

The input JSON will look like this:


{
        "savings_target": "NOMINAL",
        "benchmark_data_type": "DEFAULT",
        "min_model_r_squared": 0.6,
        "building_ids": [1, 2, 3]
}

The savings_target property must be a value from the SavingsTargetEnum. Currently, that means one of the following: CONSERVATIVE, NOMINAL, or AGGRESSIVE

The benchmark_data_type property must be a value from the BenchmarkDataEnum. Currently, that means one of the following: DEFAULT or GENERATE

The min_model_r_squared property must be a number between 0 and 1 (inclusive).

The building_ids property must be an array of integer building IDs. These buildings must be part of the current portfolio. If they're not, you can add them via the buildings API.

Building Subsets and the "All" Shortcut

Note that you don't have to include all buildings in the portfolio when creating a portfolio analytics. You can select just a subset for a particular portfolio analytics run.

If you do want all buildings from the portfolio, you can use the shortcut string "ALL" (instead of a list of integer IDs) to include all buildings in the current portfolio in this portfolio analytics.

NOTE: Use "building_ids":"ALL" to include all buildings in a portfolio in a new portfolio analytics.

The response from the server will return detailed information for the newly created portfolio analytics object. However, that object will not yet have generated results. We'll start the results generation in the next step.



 {
        "id": 19,
        "portfolio_id": 23,
        "savings_target": "NOMINAL",
        "benchmark_data_type": "DEFAULT",
        "min_model_r_squared": 0.6,
        ""portfolio_building_analytics": [
            {
                (portfolio building analytics object for each building)
            },
            ...
        ],
        "generation_result": "UNGENERATED",

        ...(other fields)...
}

Portfolio Analytics Results Calculation

After you have created a portfolio analytics, you can start the results generation process.

To do this, you call a special generate endpoint:

/api/v1/portfolios/{portfolio ID}/analytics/{ portfolio analytics ID }/generate/

Given the example results from our last step, our generate endpoint would look like this:

/api/v1/portfolios/23/analytics/19/generate/

If any errors occur the endpoint will return an error code and message. Otherwise, your portfolio analytics results generation task will now be underway!

At this point, you need to periodically 'poll' the portfolio analytics detail endpoint to find out what the generation status is.

NOTE: You must periodically poll the API to find out the result of a portfolio analytics generation.

Following our above example, the GET endpoint url would be

/api/v1/portfolios/23/analytics/19/

Continue to poll the portfolio analytics endpoint (perhaps every 10 seconds) until the generation_result field changes from IN_PROGRESS to another state.

If the analytics are successfully generated, the generation_result field will change to a COMPLETE value, and the analytics information will appear in the benchmark and assessment fields of the returned data.

If the analytics are not successfully generated, the generation_result field will change to a value of FAILED. The generation_message field will have a brief description of the error encountered when BETTER tried to generate the analytics.

Retrieve a Portfolio Analytics

You can retrieve the properties of a particular portfolio analytics run by sending a GET request to the endpoint for that portfolio analytics, using the parent portfolio's ID and the portfolio analytics ID in the endpoint:

/api/v1/portfolios/{portfolio ID}/analytics/{ analytics ID }/

For example, /api/v1/portfolio/18/analytics/29/

If the generation_result is COMPLETE, portfolio analytics data will appear in the analytics property and benchmark property.

If the generation_result is IN_PROGRESS, you can continue to poll the endpoint (perhaps every 10 seconds) until the status changes to COMPLETE or FAILED

If the generation_result is UNGENERATED, the portfolio analytics have not been generated yet. See the "Updating Portfolio Analytics" section below for how to re-run portfolio analytics

If the generation_result is INVALIDATED, this means something has changed in the portfolio, or a building in that portfolio, in a way that invalidated the previously generated portfolio analytics results. See the "Updating Portfolio Analytics" section below for how to re-run portfolio analytics

Retrieving Portfolio Analytics Detail Output in HTML Format

For this particular endpoint, an optional GET variable ?format={type} can be appended to the endpoint to specify the type of content formatting you want. The format type can be json or html. The content will be served in JSON format by default. When format is set to html, BETTER returns the result in a self-contained HTML file.

When using HTML format, an additional ?show_building_links=true GET variable can be appended to the request to add hyperlinks to the building names shown in the "Buildings" table in the report.

Listing Portfolio Analytics

You can get a complete list of portfolio analytics for a particular portfolio by sending a GET request to the /api/v1/portfolios/{ building ID }/analytics/ endpoint. The API will return a list of portfolio analytics details.

Updating Portfolio Analytics

You cannot update (PATCH or PUT) existing portfolio analytics. If you want to rerun an existing building analytics via the API, you must DELETE the existing Portfolio Analytics and then POST create it again.

Deleting a Portfolio Analytics

You can delete a portfolio analytics by sending a DELETE request to that particular portfolio analytics endpoint, using the parent portfolio's ID and the portfolio analytics ID (e.g. /api/v1/portfolios/18/analytics/29/). When you delete a portfolio analytics, any portfolio building analytics that belong to this portfolio analytics will be deleted.

Generating Net-Zero Information

If you want to generate net-zero information for a portfolio analytics run using PVWatts®, you must include the enable_pvwatts boolean variable in your request when first creating your portfolio analytics. When you generate the results, they will include net-zero information at both the building level and the portfolio level.

IMPORTANT: Only buildings that have enabled PVWatts® will be included in the net-zero calculations. See the buildings API docs for more details.

An example request that includes a request for net-zero information to be calculated using PVWatts®:


{
    "savings_target": "NOMINAL",
    "benchmark_data_type": "DEFAULT",
    "min_model_r_squared": 0.6,
    "enable_pvwatts": "true"
}

API Response Field Names

The response from the following GET endpoint:

/api/v1/portfolios/{ portfolio ID}/analytics/{ portfolio analytics ID }

First-level fields:

Field Description Unit
id Unique identifier for the BuildingAnalytics instance N/A
benchmark_data_country Two-letter country code for the benchmark data N/A
generation_result Result status of the generation process (e.g., UNGENERATED, COMPLETE, FAILED) N/A
generation_message Message detailing the result of the generation process N/A
generation_date Timestamp of when the generation process was completed ISO 8601
task_id Identifier for the associated Celery task, if any N/A
dict_portfolio_analytics_results Dictionary containing various analytics results for the portfolio (see details here) N/A
portfolio_building_analytics List of analytics results for individual buildings in the portfolio (see details here) N/A
portfolio Identifier for the associated portfolio N/A
min_model_r_squared Minimum R-squared value for model validation N/A
savings_target Target for savings (i.e., CONSERVATIVE, NOMINAL, AGGRESSIVE) N/A
benchmark_data_type Type of benchmark data used (i.e., DEFAULT, GENERATE) N/A
use_pvwatts Boolean indicating if PVWatts analytics is used N/A
warning_message Warning message related to the portfolio analytics N/A

`dict_portfolio_analytics_results` Details

Field Description Unit
measure_counts Dictionary containing counts of various energy efficiency measures N/A
total_floor_area Total floor area of the portfolio
total_ghg_savings_c Total greenhouse gas savings in CO2 equivalent for electricity and fossil fuel combined kg CO2e
total_ghg_savings_e Total greenhouse gas savings in CO2 equivalent for electricity kg CO2e
total_ghg_savings_f Total greenhouse gas savings in CO2 equivalent for fossil fuel kg CO2e
total_building_count Total number of buildings in the portfolio N/A
total_cost_savings_c Total cost savings for electricity and fossil fuel combined USD
total_cost_savings_e Total cost savings for electricity USD
total_cost_savings_f Total cost savings for fossil fuel USD
total_energy_savings_c Total energy savings for electricity and fossil fuel combined kWh
total_energy_savings_e Total energy savings for electricity kWh
total_energy_savings_f Total energy savings for fossil fuel kWh
total_eui_target_pred_c Predicted energy use intensity target for electricity and fossil fuel combined kWh/m²
total_eui_target_pred_e Predicted energy use intensity target for electricity kWh/m²
total_eui_target_pred_f Predicted energy use intensity target for fossil fuel kWh/m²
total_ghg_savings_pct_c Percentage of greenhouse gas savings for electricity and fossil fuel combined %
total_ghg_savings_pct_e Percentage of greenhouse gas savings for electricity %
total_ghg_savings_pct_f Percentage of greenhouse gas savings for fossil fuel %
total_ghg_target_pred_c Predicted greenhouse gas target for electricity and fossil fuel combined kg CO2e
total_ghg_target_pred_e Predicted greenhouse gas target for electricity kg CO2e
total_ghg_target_pred_f Predicted greenhouse gas target for fossil fuel kg CO2e
total_cost_savings_pct_c Percentage of cost savings for electricity and fossil fuel combined %
total_cost_savings_pct_e Percentage of cost savings for electricity %
total_cost_savings_pct_f Percentage of cost savings for fossil fuel %
total_cost_target_pred_c Predicted cost target for electricity and fossil fuel combined USD
total_cost_target_pred_e Predicted cost target for electricity USD
total_cost_target_pred_f Predicted cost target for fossil fuel USD
total_eui_current_pred_c Predicted current energy use intensity for electricity and fossil fuel combined kWh/m²
total_eui_current_pred_e Predicted current energy use intensity for electricity kWh/m²
total_eui_current_pred_f Predicted current energy use intensity for fossil fuel kWh/m²
total_eui_savings_pred_c Predicted energy use intensity savings for electricity and fossil fuel combined kWh/m²
total_eui_savings_pred_e Predicted energy use intensity savings for electricity kWh/m²
total_eui_savings_pred_f Predicted energy use intensity savings for fossil fuel kWh/m²
total_ghg_current_pred_c Predicted current greenhouse gas emissions for electricity and fossil fuel combined kg CO2e
total_ghg_current_pred_e Predicted current greenhouse gas emissions for electricity kg CO2e
total_ghg_current_pred_f Predicted current greenhouse gas emissions for fossil fuel kg CO2e
total_cost_current_pred_c Predicted current cost for electricity and fossil fuel combined USD
total_cost_current_pred_e Predicted current cost for electricity USD
total_cost_current_pred_f Predicted current cost for fossil fuel USD
total_energy_savings_pct_c Percentage of energy savings for electricity and fossil fuel combined %
total_energy_savings_pct_e Percentage of energy savings for electricity %
total_energy_savings_pct_f Percentage of energy savings for fossil fuel %
total_energy_target_pred_c Predicted energy target for electricity and fossil fuel combined kWh
total_energy_target_pred_e Predicted energy target for electricity kWh
total_energy_target_pred_f Predicted energy target for fossil fuel kWh
total_energy_current_pred_c Predicted current energy consumption for electricity and fossil fuel combined kWh
total_energy_current_pred_e Predicted current energy consumption for electricity kWh
total_energy_current_pred_f Predicted current energy consumption for fossil fuel kWh
total_ghg_intensity_target_pred_c Predicted greenhouse gas intensity target for electricity and fossil fuel combined kg CO2e/m²
total_ghg_intensity_target_pred_e Predicted greenhouse gas intensity target for electricity kg CO2e/m²
total_ghg_intensity_target_pred_f Predicted greenhouse gas intensity target for fossil fuel kg CO2e/m²
total_ghg_intensity_current_pred_c Predicted current greenhouse gas intensity for electricity and fossil fuel combined kg CO2e/m²
total_ghg_intensity_current_pred_e Predicted current greenhouse gas intensity for electricity kg CO2e/m²
total_ghg_intensity_current_pred_f Predicted current greenhouse gas intensity for fossil fuel kg CO2e/m²
total_ghg_intensity_savings_pred_c Predicted greenhouse gas intensity savings for electricity and fossil fuel combined kg CO2e/m²
total_ghg_intensity_savings_pred_e Predicted greenhouse gas intensity savings for electricity kg CO2e/m²
total_ghg_intensity_savings_pred_f Predicted greenhouse gas intensity savings for fossil fuel kg CO2e/m²

`portfolio_building_analytics` Details

Field Description Unit
id Unique identifier for the building analysis entry Integer
building_id Unique identifier for the building Integer
savings_target Target savings category (e.g., "NOMINAL") String
benchmark_data_type Type of benchmark data used (e.g., "DEFAULT") String
benchmark_data_country Country associated with the benchmark data String (ISO country code)
min_model_r_squared Minimum R-squared value for the model Float
generation_result Status of the generation process (e.g., "COMPLETE") String
generation_date Timestamp when the generation process was completed ISO 8601 DateTime
generation_message Message describing any errors or warnings during generation String (Nullable)
inverse_model Reference to the inverse model used in the analysis Integer (Nullable)
assessment Reference to the building's assessment ID Integer
benchmark Reference to the building's benchmark ID Integer
pvwatts_analytics Reference to PVWatts analysis data, if available Integer (Nullable)