Ecobee Home Power Monitoring

I have an Ecobee Smart Si Thermostat which has ZigBee built into it, normally you would configure it to allow you to connect room sensors, but it can also function as a utility meter for meters that support it. This allows you to monitor home energy usage. The utility provider I have, SDGE, has the Smart Si on its compatible list, and I have my thermostat configured to monitor my power usage. I was hoping this data could be added to home assistant, especially with all the new energy monitoring features added. I checked EcoBee’s API documentation and the API does support pulling meter data.

Isn’t this an old, discontinued model? It no longer appears on ecobee’s product list.

I’m not sure, but definitely could be, this thermostat was in the house when it was purchased, the previous owner had it.

It’s very unlikely anyone will spend time developing an integration for a discontinued product. Even if someone did want to do it, the first hurdle would be to get one.

Basically, the field is narrowed to someone who already owns one and has the required software development skills, and interest, to tackle the project.


Can you currently integrate this model using the existing ecobee thermostat integration?

I understand, that makes sense. The Smart Si still works with the current EcoBee integration, and I did manage to figure out how to use the curl commands in the examples and was able to pull utility data. However, I barely know any python so I wouldn’t even know where to begin adding support or how to format the data in a way home assistant would understand.

Ah! If this old model is supported by the existing integration then there’s a glimmer of hope. However, it will depend on whether the new models also support connecting to a utility meter. If they don’t then we’re back to the original problem of creating something that only works for a discontinued product.

Is this part of the eco+ service?

Interesting that’s good to hear. I have no idea if any other of their thermostats have this feature, or even if the meters that support this feature are that common either, but some hope is better than none.

Sadly from the quick research I did the ecobee Smart and ecobee Smart Si seem to be the only ones that ever had this feature.

I don’t think so, the Smart Si wasn’t in the list of compatible devices.

So with my basic knowledge and a lot of Googling, I made a python script to use with the command_line sensor. So if there is somehow someone else in the same situation I am, they can use my janky script (Or turn it into a proper component). I looked into making this into a custom component, but that is beyond my abilities. The script will output the current months’ usage up to the time the command was run. The value_template and json_attributes from the command line sensor allows the sensor to work with the energy monitoring without having to change anything. Just change the API key at the top and generate and add the refresh token and everything should work. You can then use the Utility Meter component to get daily and yearly stats.

utility_meter:
  ecobee_daily_energy:
    source: sensor.ecobee_monthly_energy
    name: ecobee Daily Energy
    cycle: daily
  ecobee_yearly_energy:
    source: sensor.ecobee_monthly_energy
    name: ecobee Yearly Energy
    cycle: yearly

This is the command line sensor I used:

- platform: command_line
    scan_interval: 900 # 15 Minutes is the rate limit for the ecobee API.
    command_timeout: 30
    name: ecobee Monthly Energy
    command: python3 /config/ecobee-energy.py
    value_template: "{{ value_json.state }}"
    json_attributes:
      - unit_of_measurement
      - device_class
      - state_class
      - last_reset

Just put the following python script in the /config directory named ecobee-energy.py:

import requests
import json
from datetime import date

thermostatNumber = 0 # I only have one thermostat and since you wouldn't need more than one monitoring utilities I didn't bother coding for more than one, if you have more than one you may need to change this (i.e 1 for the second 2 for the third etc.)

# API key from Developer Page see https://www.home-assistant.io/integrations/ecobee and https://www.ecobee.com/home/developer/api/examples/ex1.shtml 
api = 'ENTER API KEY HERE'
# Refrash token, lasts for 1 year you can generate one here: https://www.ecobee.com/home/developer/api/examples/ex1.shtml
refresh_token = 'ENTER REFRESH TOKEN HERE'

def getAccessToken(refresh_token, api):
    # Get access token to pull data from api
    headers = {"Content-Type": "text/json"}
    url = 'https://api.ecobee.com/token?grant_type=refresh_token&code=' + refresh_token + '&client_id=' + api

    try:
        results = requests.post(url, headers = headers, timeout=10).json()
        access_token = results["access_token"]
        return access_token
    except:
        print('unavailable')
        exit()

def getThermostatID(access_token):
    # Get list of thermostats
    body = {
        "selection": {
            "selectionType": "registered",
            "selectionMatch": "",
            "includeEquipmentStatus": "false"
        }
    }
    url = 'https://api.ecobee.com/1/thermostatSummary?json=' + json.dumps(body)
    headers = {"Content-Type": "application/json;charset=UTF-8", "Authorization": "Bearer " + access_token }
    try:
        results = requests.get(url, headers = headers, timeout=10).json()
        thermostatID = results["revisionList"][0].split(':')[thermostatNumber] # I only have one thermostat and since you wouldn't need more than one monitoring utilities I didn't bother coding for more than one
        return thermostatID
    except:
        print('unavailable')
        exit()

def getThisMonthsUsage(access_token, thermostatID):
    # API allows up to 31 days, API usage DO NOT request report data at an interval quicker than once every 15 minutes
    todaysDate = date.today().strftime("%Y-%m-")
    startDate = todaysDate + '01'
    endDate = todaysDate + '31'
    body = {
        "startDate": startDate,
        "endDate": endDate,
        "meters": "energy",
        "selection": {
            "selectionType": "thermostats",
            "selectionMatch": thermostatID
        }
    }

    url = 'https://api.ecobee.com/1/meterReport?format=json&body=' + json.dumps(body)
    headers = {"Content-Type": "text/json", "Authorization": "Bearer " + access_token }

    try:
        results = requests.get(url, headers = headers, timeout=10).json()
        kWh = 0.0
        for i in results["reportList"][0]["meterList"][0]["data"]:
            energy = i.split(',')
            kWh += float(energy[3])
        kWhTotal = round(kWh, 3)
        return kWhTotal
    except:
        print('unavailable')
        exit()

def getTodaysUsage(access_token, thermostatID):
    # API allows up to 31 days, API usage DO NOT request report data at an interval quicker than once every 15 minutes
    todaysDate = date.today().strftime("%Y-%m-%d")
    startDate = todaysDate
    endDate = todaysDate
    body = {
        "startDate": startDate,
        "endDate": endDate,
        "meters": "energy",
        "selection": {
            "selectionType": "thermostats",
            "selectionMatch": thermostatID
        }
    }

    url = 'https://api.ecobee.com/1/meterReport?format=json&body=' + json.dumps(body)
    headers = {"Content-Type": "text/json", "Authorization": "Bearer " + access_token }

    try:
        results = requests.get(url, headers = headers, timeout=10).json()
        kWh = 0.0
        for i in results["reportList"][0]["meterList"][0]["data"]:
            energy = i.split(',')
            kWh += float(energy[3])
        kWhTotal = round(kWh, 3)
        return kWhTotal
    except:
        print('unavailable')
        exit()




access_token = getAccessToken(refresh_token, api)
thermostatID = getThermostatID(access_token)
kWhTotal = getThisMonthsUsage(access_token, thermostatID)
# kWhTotal = getTodaysUsage(access_token, thermostatID)

unit = "kWh"
unique_id = "ecobee_" + thermostatID + "_energy_monthly"
# unique_id = "ecobee_" + thermostatID + "_energy_daily"
entity_id = "ecobee_" + thermostatID + "_energy_monthly"
# entity_id = "ecobee_" + thermostatID + "_energy_daily"
friendly_name = "ecobee Energy Usage Monthly"
# friendly_name = "ecobee Energy Usage Daily"
device_class = "energy"

todaysDate = date.today().strftime("%Y-%m-")
# todaysDate = date.today().strftime("%Y-%m-%d")
startDate = todaysDate + '01'
# startDate = todaysDate
last_reset = startDate + "T00:00:00"
state = str(kWhTotal)

output = {
    "unit_of_measurement": unit,
    # "unique_id": unique_id,
    # "entity_id": entity_id,
    # "friendly_name": friendly_name,
    "device_class": device_class,
    "state_class": "measurement",
    "last_reset": last_reset,
    "state": state
}
print(json.dumps(output))

Did you have energy sensors created automatically when you first set up the integration? I have an ecobee Smartthermostat and am also with SDGE, but I don’t see any extra sensors created for energy.

Would I just need to add that python script? Also, I live in an apartment building, so I’m not sure if the service is available to me…I read somewhere that it’s only for homeowners.

The ecobee integration doesn’t support power usage.

You have to first set up the thermostat to connect to your meter in the zigbee settings on the thermostat and give sdge the necessary info online(MAC and Install Code if I remember correctly). I don’t know how it works in apartments, but if you have a meter just for your apartment and it is in range of your thermostat you might be able to do it.

After you connect the meter to your thermostat the python script can poll ecobee’s api and pass that data to home assistant using the command_line integration which I showed above.