Ecobee: Customizing Hold Modes in Home Assistant
For more than a few years, I’ve been using Home Assistant to run our home automations and smart home devices. I’ve always loved pretty much everything about it. However, one of the few things I disliked was their integration of Ecobee thermostats – of which we have two.
The Main Issue
My main issue with the HA / Ecobee integration is that when you use HA to change the temperature, it will always set the new temperature to take effect until the next scheduled transition (as defined by the Ecobee schedule). In the context of trying to balance comfort against costs, this might not always be what you want.
For example, your next schedule change may not be for several hours. So, what if you just want to cool down or warm up the house for just a few minutes rather than spending extra money on electricity keeping the HVAC at a lower/higher temperature for several hours? Or, perhaps you want the temperature set to run indefinitely, rather than just until the next scheduled transition?
With the default install of Home Asisstant, this is not possible. However, HA is open source. So, I decided to make some changes that would allow this to work the way I’m describing. The library that Home Assistant uses to interface with the Ecobee API is also open source. I have my Home Assistant running as a Docker container, so this method of making this work has only been tested and confirmed working with a Docker install. It may work with other HA installs, but I cannot confirm that.
In order to make this work, you’ll need to accomplish two main tasks:
- Create a custom component for Home Assistant to override the base HA Ecobee component.
- Create a custom version of the Python Ecobee API library that Home Assistant uses to talk to the Ecobee API.
You’ll want to track these changes, as well as make sure they’re current with the current version of both Home Assistant and the Python Ecobee API. I chose to fork both of these repositories to my own personal GitHub rather than just cloning them. You can do this via a simple clone if you wish.
Cloning the Ecobee API
I created a new directory to hold my custom components. Then I cloned the Python Ecobee API into a sub-directory of that.
hass:~$ pwd /home/hass hass:~$ mkdir custom hass:~$ cd custom hass:~/custom$ mkdir dependencies hass:~/custom$ cd dependencies/ hass:~/custom/dependencies$ git clone https://github.com/nkgilley/python-ecobee-api.git Cloning into 'python-ecobee-api'... remote: Enumerating objects: 26, done. remote: Counting objects: 100% (26/26), done. remote: Compressing objects: 100% (19/19), done. remote: Total 475 (delta 9), reused 20 (delta 7), pack-reused 449 Receiving objects: 100% (475/475), 96.00 KiB | 2.18 MiB/s, done. Resolving deltas: 100% (226/226), done.
We’ll need to modify the Python Ecobee API to be able to tell the Ecobee to hold for a certain number of hours rather than until the next schedule transition. There is only one file (pyecobee / __init__.py) you’ll need to change. First, create a new branch to hold your changes (shown in the the code snippet below). Then this GitHub commit diff will show you the changes you need to make.
QUICK NOTE: the diff (on line 289) shows removing a hold_type variable assignment. This line is not in the production code. That was my “quick and dirty” way of setting holdHours before I went down the road of setting this all up to make it easily changeable.
hass:~/custom/dependencies$ cd python-ecobee-api hass:~/custom/dependencies/python-ecobee-api$ git checkout -b holdHours.20200424 Switched to a new branch 'holdHours.20200424'
The holdHours.20200424 branch from my fork of the repository has these changes already made. It should be public, if you wish to use it without making the changes yourself. I have created a pull request to hopefully get these merged into the main library master branch. An update will be made if/when the changes are merged.
UPDATE 5/23/2020: My changes to the Python Ecobee API have been merged into the master branch. They should be available by default going forward. The next time I update Home Assistant and can confirm that this works without that special fork, I will update the post accordingly.
UPDATE 8/28/2020: I can confirm that as of at least Home Assistant version 0.114.3, the Python Ecobee API changes are included in Home Assistant and no longer necessary.
We’ve made these changes to the Python Ecobee API library. Now, we need to modify Home Assistant to allow it to use them. Clone the Home Assistant Core, so that we can make the necessary changes.
hass:~/custom$ git clone https://github.com/home-assistant/core.git hass-core Cloning into 'hass-core'... remote: Enumerating objects: 191, done. remote: Counting objects: 100% (191/191), done. remote: Compressing objects: 100% (150/150), done. remote: Total 264352 (delta 49), reused 125 (delta 39), pack-reused 264161 Receiving objects: 100% (264352/264352), 158.69 MiB | 2.49 MiB/s, done. Resolving deltas: 100% (186768/186768), done. Checking out files: 100% (11470/11470), done.
Before making any changes, you should check out the tag corresponding to the version of Home Assistant you have installed. Create a new branch from that point. In my example (as you can see in the last few lines of the code snippet below), I’m using HA 0.108.1.
hass:~/custom/hass-core$ git checkout 0.108.1 Checking out files: 100% (11808/11808), done. Note: checking out '0.108.1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at eb718bffe0 Merge pull request #33862 from home-assistant/rc hass:~/custom/hass-core$ git checkout -b additional_hold_modes Switched to a new branch 'additional_hold_modes'
The component file you’ll need to change is hass-core / homeassistant / components / ecobee / climate.py. This commit diff shows the changes that need to be made.
My fork of the repository is public. The changes described here are available in the additional_hold_modes branch, should you wish to use them rather than making the changes yourself. I plan to update both of these branches as the HA Core and Python Ecobee API as necessary.
Once we have made these changes, we need to link them together. I use Docker Compose to set up my HA stack. The relevant part of the docker-compose.yml file is shown here.
services: hass: container_name: hass_hass image: homeassistant/home-assistant:latest volumes: - /home/hass/config:/config - /etc/localtime:/etc/localtime:ro - /home/hass/custom/hass-core/homeassistant/components/ecobee:/config/custom_components/ecobee - /home/hass/custom/dependencies/python-ecobee-api/pyecobee:/usr/local/lib/python3.7/site-packages/pyecobee restart: always ports: - 8123:8123 depends_on: - mysql - nodered networks: - default - docker-compose_default
Some of this is beyond the scope of this post. I’d be happy to do an additional write-up of the rest of my configuration if there’s interest. The main points you’ll notice though are the last two volume mounts on the Home Assistant container. We’re using these to map our custom dependencies and components into the correct locations in the docker container.
If we do nothing else, HA will function exactly as it did before we made any changes. We need to make one more change in order to have the Home Assistant Core install use the new holdHours option. The Ecobee component changes we made will look for two variables in your configuration: ecobee_hold_mode and ecobee_hold_hours. The following is a snippet from my configuration.yaml file, concerning these two new variables:
input_select: ecobee_hold_mode: name: Ecobee Hold Mode options: - nextTransition - holdHours - indefinite initial: holdHours input_number: ecobee_hold_hours: name: Ecobee Hold Hours initial: 2 min: 1 max: 4 step: 1
The initial and maximum values for ecobee_hold_hours can be modified, but the minimum cannot be set below 1. I did not see a maximum value specified in the API documentation. But I chose 4 for simplicity (you may be able to set this higher if you choose). The step must be set in full integer increments, fractional hours are not supported by the API.
Once you have these variables configured, you can add them to your UI layout. This gives you the ability to change both the hold mode and number of hours to hold on the fly. The hold hours parameter will be ignored if the hold mode is set to next Transition or indefinite.
At this point, all you need to do is bring up the container. Or re-create it if you already had it running.
hass:~$ docker-compose up -d hass Recreating hass_hass ... done
See all Reviews in our Product Review Portal.
Ecobee: Customizing Hold Modes in Home Assistant – End Notes
That’s all there is to it. Your Home Assistant install should now be using the custom components and dependencies you’ve created.
NOTE: Any temperature changes from within HA, both via the UI and via any automations you might have, will use the new components and library.
For example, I use Node Red for my automations. Anything in Node Red that calls the HA services to change the temperature will use the custom components (and as such will look at the custom variables to determine what hold mode to use).