There’s no question here
To the uninitiated, the ecobee is a cloud-first smart thermostat that utilizes remote sensors to attempt to optimize your home’s temperature based on room occupancy. A novel idea, especially if your thermostat is located near warm windows or the front door like ours, but I believe we can do a whole lot better!
Taking a Look at Ecobee
First, let’s discuss the initial cost you will incur before you even get the system installed. These things are fairly pricey – around $250 for the thermostat and one sensor – and it gets more expensive if you have a lot of rooms. Assuming you want sensors in your bedroom, living room, office, kids’ rooms, dining room and family room, you’re looking at $500 to ensure comfort in any room of your home.
Alright, you just dropped a good chunk of change on your brand new smart climate control, time to install it! Do you have an older home like we do? You’re HVAC system probably does not include a C-wire – not to worry, the system comes with a power-extender kit, which only requires a little rewiring inside your furnace control panel. Assuming you haven’t electrocuted yourself, the main unit is now mounted on the wall where your old thermostat was – unless you decided to go all-out and run wires to a new more optimum location (hope you have some fish tape…).
You’re not done yet, it’s time to place the remote sensors around your house. Make sure to choose locations such that the sensor can see the room, won’t be artificially affected by sun through windows and, most importantly, receive fairly consistent motion when the room is occupied. Why? Well, unlike occupancy sensors – which can detect if a person is in the room regardless of motion, these remote sensors rely on a motion-timeout mechanism; basically, if the sensor will only report occupancy if it detects motion within a certain timeframe. You might want to rethink putting that sensor where you primarily watch movies or television, if your comfort settings are not set correctly, 2 hours into your 15th viewing of Avatar it may just switch to away mode.
Finally, your system is installed, set up and keeping your house comfortable – but this wouldn’t be a very smart thermostat if it didn’t prepare your home for optimum comfort on your way home, now would it? Well, it’s a good thing the companion app utilizes geofencing to preemptively switch to home mode on your way back from 4 hour trip to IKEA! Let’s just hope you live alone or always travel with your family, since this feature is limited to one user without the help of 3rd party applications like Life,360 or AFAIK.
If a Company like Ecobee Has These Issues, What Can I Do?
Problem 1: Cost
This is an easy one, go to Amazon and look for a thermostat that integrates with your home’s smart protocols – Zigbee, Z-Wave, Thread/Bluetooth, Wi-Fi – you’ll find thousands of options. Make sure to read the reviews and find a quality thermostat, we have a GoControl GC-TBZ48 which I found on Amazon a few years ago for around $115 but seems to run about $150 now. Don’t forget eBay, you can find used or near-new units even cheaper.
Problem 2: Installation/No C-Wire
If you have no C-Wire, there are plenty of battery-powered options to avoid scary electrical work out there as well. The unit linked above can operate off of the 24VAC transformer in your furnace, as well as the 6V provided by 4 AA batteries included with the unit.
Problem 3: Remote Sensor Cost
Like Problem 1, you’ll find a plethora of options for temperature and motion sensors for whatever protocols your home uses on Amazon. If you have a lot of Philips Hue products, the Hue Motion Sensor provides motion and temperature readings and can be found cheap on eBay. If your protocol of choice is Z-Wave, I recommend Aeotec make reliable devices that are highly configurable, including 3 and 6 sensor devices – however, they cost about as much as the ecobee remote sensors, so check out Monoprice for white-label Z-Wave devices to save some cash. If you look around, you’ll find a decent device that fits your price point.
Problem 4: Lack of Motion
Unfortunately, there’s no universal solution to solving the lack of motion issue; there are, however, plenty of DIY solutions. A simple solution: the Aeotec sensors have configurable sensitivity, reporting thresholds, alert timeout and motion time out settings – adjusting these can virtually eliminate the lack of motion issue. Serious DIYers might look into using Time-of-Flight sensors to keep track of people entering and exiting a room, similar to this Instructables project. For a fool-proof method, some cheap webcams, or even Raspberry Pi 0 Ws with camera modules, and TensorFlow or OpenCV can literally detect people and faces if you don’t mind installing cameras around your house – and facilitate a future project I’d like to take on to pause/play the movie based on the number of faces/people changing in the room.
Problem 5: Geofencing
The single-user geofencing “feature” of ecobee is a non-issue to most home automators. I’m going to assume you either have GPS tracking set up if not, checkout Home-Assistant + Companion Mobile App with zones and proximity, it’s fairly user friendly and has most of this built in.
Let’s See How a We Can Do Better
Following Agile practices, let’s create some feature stories, a feature story usually includes a title, statement of intent, acceptance criteria list and possibly stretch goals. Below are some cards describing the features I would like to implement in our comfort system
As a smart-home owner
I would like the house to be comfortable when I get home
so that I do not have to wait be comfortable
Acceptance Criteria
- Home mode is set when a family member is within a certain radius from home and traveling towards home
- Do nothing if someone is home and climate is set to home mode
- Return climate to away mode if family member leaves the radius or travels away from home
Stretch Goal ACs
- Set home mode based one calendar event end time and ETA from event to home
As a smart-home owner
I would like to adjust the sensor readings for calibration or offset
so that temperature readings are reliable
Acceptance Criteria
- Sensor readings are offset by a specified calibration value
Stretch Goal ACs
- Adjust offset based on sun or detected light levels
As a smart-home owner
I would like areas to be ranked by traffic levels
so that high-traffic areas have a greater impact than low-traffic areas
Acceptance Criteria
- Sensors have a base weight used for averaging
- Sensors have an adjusted weight when an area is triggered for averaging
Stretch Goal ACs
- Adjust weights based on historical traffic data
As a smart-home owner
I would like the climate adjust based on the preferences of guests
so that my guests are more comfortable
Acceptance Criteria
- Guests can specify a preferred temperature or fan settings
- Climate adjusts when a guest with preferred climate settings arrives
- Climate reverts back when guest with preferred climate settings departs
Stretch Goal ACs
- When multiple preferred climate guests are present, climate adjustments are averaged if needed
Climate on Demand
You may have guessed, but we run Home-Assistant, amongst other projects, in our home. Robbie Trencheny created a wonderful mobile application for iOS that has grown and been forked for Android systems. Using some of the native integrations we can easily create a ruleset to achieve our goal of arriving home to a comfortable client.
To follow in our footsteps, you’ll need to have Home-Assistant setup and running with the following integrations configured:
- mobile_app – This allows the Companion Mobile App to communicate with the Home-Assistant server
- person – Create a person entity for each person you which to track and tie it to the device_tracker added via mobile_app with succinct names like “Dad” or “Mom”
- zone – You will want to set up a “Thermostat” zone with a decent radius to act as the threshold for determining if a user is heading home or not
- proximity – Set up a proxy entity for each person you wish to determine the proximity to zone.home, using a naming convention such as “Home Dad” or “Home Mom”
- group – Create a group entity that contains all of the person entities above
- climate – The appropriate integration for your smart thermostat
Here is a very basic example configuration file to get you going, add the appropriate configuration for your thermostat for your home:
## configuration.yaml
...
mobile_app:
person:
- name: Dad
id: dad123
device_trackers:
- device_tracker.dad
- name: Mom
id: mom321
device_trackers:
- device_tracker.mom
group:
family:
name: Family
entities:
- person.dad
- person.mom
zone:
- name: Thermostat
latitude: !secret latitude_home
longitude: !secret longitude_home
radius: 1700 # Just over a mile
icon: mdi:thermostat
proximity:
home_dad:
zone: home
devices:
- person.dad
tolerance: 50
unit_of_measurement: mi
home_mom:
zone: home
devices:
- person.mom
tolerance: 50
unit_of_measurement: mi
automation: !include_dir_list automations
# automations/prepare_climate_home.yaml
# This assumes your thermostat supports preset modes, if not adjust service call appropriately, i.e. climate.set_temperature
name: Prepare Climate Home Mode
trigger:
# Trigger automation when Mom or Dad enter the Thermostat Zone
- platform: zone
entity_id:
- person.mom
- person.dad
zone: zone.thermostat
event: enter
condition:
# Only run automation if no one is home and the person that triggered the
# automation is heading towards from Home
- condition: not
conditions:
- condition: state
entity_id: group.family
state: home
- condition: template
value_template: "{{ is_state_attr('proximity.home_' + (states.person | selectattr('entity_id', 'eq', trigger.entity_id) | map(attribute='entity_id') | map('replace', 'person.', '') | list | first), 'dir_of_travel', 'towards') }}"
- condition: state
entity_id: "{{ trigger.entity_id }}"
state: "Thermostat"
action:
# Set the thermostat to home mode
- service: climate.set_preset_mode
data:
entity_id: climate.thermostat
preset_mode: home
# automations/prepare_climate_away.yaml
# This assumes your thermostat supports preset modes, if not adjust service call appropriately, i.e. climate.set_temperature
name: Prepare Climate Away Mode
trigger:
# Trigger automation when Mom or Dad leave the Thermostat Zone
- platform: zone
entity_id:
- person.mom
- person.dad
zone: zone.thermostat
event: leave
condition:
# Only run automation if no one is home and the person that triggered the
# automation is heading away from Home
- condition: state
entity_id: group.family
state: home
- condition: template
value_template: "{{ is_state_attr('proximity.home_' + (states.person | selectattr('entity_id', 'eq', trigger.entity_id) | map(attribute='entity_id') | map('replace', 'person.', '') | list | first), 'dir_of_travel', 'away_from') }}"
- condition: state
entity_id: "{{ trigger.entity_id }}"
state: "not_home"
action:
# Set the thermostat to away mode
- service: climate.set_preset_mode
data:
entity_id: climate.thermostat
preset_mode: away
Summarizing the Configuration Above
The first automation will set the home mode if a user enters the Thermostat radius and direction of travel is towards home, as long as no one is home already.
The second automation will set the away mode if a user leaves the Thermostat radius and direction of travel is away from home, as long as no one is home still.
Definition of Done
- ✓ : Home mode is set when a family member is within a certain radius from home and traveling towards home
- ✓ : Do nothing if someone is home and climate is set to home mode
- ✓ : Return climate to away mode if family member leaves the radius or travels away from home
Sensor Calibration
# sensors/temperature_calibrations
sensor:
- platform: template
# Creates a sensor that is always 1 degree lower than what the kitchen temperature report
kitchen_calibrated_temperature:
name: Calibrated Kitchen Temperature
value_template: "{{ (states.sensor.kitchen_temperature.state | int) - 1 }}
icon: mdi:thermometer
unit_of_measurement: "\u2109"
device_class: temperature
...
Summarizing the Configuration Above
By utilizing the template sensor, you are able to apply any transformation to the reported sensor values you wish. In the example above, it is creating a new sensor that will always be 1 degree lower than the device’s reported temperature.
Definition of Done
- ✓ : Sensor readings are offset by a specified calibration value
Room/Area Ranked Priority
Using a simple weighted-average algorithm fulfills this requirement. Each room or temperature sensor can have a default weight, as wells a triggered weight; the triggered weight will be used when the occupancy/motion sensor associated with this temperature reading detects motion. You can accomplish this with the Template Sensor integration, or you can utilize something like AppDaemon and use Python to calculate this.
# sensors/temperature_ranking
platform: template
sensors:
thermostat_internal_offset:
name: Thermostat Internal Offset
value_template: "{{ climate.thermostat.attributes.offset }}"
icon: mdi:thermometer-plus
unit_of_measurement: "\u2109"
device_class: temperature
thermostat_actual_temperature:
name: Thermostat Internal Offset
value_template: "{{ (states('sensor.thermostat_temperature') | float) - (states('sensor.thermostat_internal_offset') | float) }}"
icon: mdi:thermometer-lines
unit_of_measurement: "\u2109"
device_class: temperature
average_temperature:
name: Average Home Temperature
value_template: |
{%- set weights =
{
"sensor.kitchen_temperature": {
"weight": 0.8
"triggered_weight": 1.2
"triggered_by: {
"entity_id": "binary_sensor.kitchen_motion"
"state": "on"
}
},
"sensor.living_room_temperature: {
"weight": 1.0,
"triggered_weight": 2.1
"triggered_by: {
"entity_id": "binary_sensor.living_room_motion"
"state": "on"
}
},
... # Add all sensors and their weight data here
} -%}
{%- set ns = namespace(temperature=0.0, total_weight=0.0) -%}
{%- for sensor, weight_data in weights.items() -%}
{%- if 'triggered_weight' in weight_data and 'triggered_by' in weight_data and is_state(weight_data['triggered_by']['entity_id'], weight_data['triggered_by']['state']) -%}
{%- set ns.temperature = ns.temperature + (states(sensor) | float) * (weight_data['triggered_weight'] | float) -%}
{%- set ns.total_weight = ns.total_weight + (weight_data['triggered_weight'] | float) -%}
{%- else -%}
{%- set ns.temperature = ns.temperature + (states(sensor) | float) * (weight_data['weight'] | float) -%}
{%- set ns.total_weight = ns.total_weight + (weight_data['weight'] | float) -%}
{%- endif -%}
{%- endfor -%}
{{ None if ns.total_weight == 0.0 else (ns.temperature / ns.total_weight) }}
icon: mdi:thermometer
unit_of_measurement: "\u2109"
device_class: temperature
# automations/thermostat_offset.yaml
name: Set Thermostat Internal Offset
trigger:
- platform: state
entity_id: sensor.average_temperature
action:
- service: mqtt.publish
data:
topic: "OpenZWave/1/command/setvalue/"
payload_template: '{ "ValueIDKey": 12345, "Value": {{ ((states('sensor.average_temperature') | float )
- (states('sensor.thermostat_actual_temperature') | float)) | round('half') }} }'
Summarizing the Configuration Above
First, we define some Template Sensors to facilitate the arithmetic and automations that follow. Since our automation will adjust the internal offset of the thermostat so that the reported temperature of the thermostat is actually the weighted average temperature, we need to know what the “actual” thermostat temperature is without the offset applied and, for ease of use, what the thermostat’s current offset is. Now that we have these two sensors (sensor.thermostat_internal_offset, sensor.thermostat_actual_temperature), we can use the values of these entities to calculate what the offset should be every time the average temperature sensor changes. Now, it doesn’t really matter where in your house the thermostat is mounted, because the temperature it’s reporting is ignored and, effectively, replaced with what we have calculated to be the temperature in the house based on occupancy and weights (or “rank” if you prefer).
Definition of Done
- ✓ : Sensors have a base weight used for averaging
- ✓ : Sensors have an adjusted weight when an area is triggered for averaging
Personalized Comfort
If you are like us, you want your friends and guests to be comfortable in your home – or maybe your significant other prefers the house a little cooler than you do. Personalized comfort allows you to accommodate some of the common requests you may receive, such as:
- “I run hot, can we kick the AC up a bit?”
- “It’s stuffy in here, is it ok if I turn on the fan?”
- “I prefer natural light, would you mind if I opened the blinds?”
# customization.yaml
person.bob:
target_temp: 72
person.jim
fan_speed: low
person.annie
window_coverings: open
# automations/personal_comfort.yaml
name: Personal Comfort Settings
trigger:
- platform: state
entity_id:
- person.bob
- person.jim
- person.annie
action:
- choose:
- conditions:
- condition: template
value_template: >-
{{ state_attr(trigger.entity_id, "target_temp") != None }}
sequence:
- service: climate.set_temperature
data:
entity_id: climate.thermostat
temperature: "{{ (states.input_number.target_temperature.state | int) if is_state(trigger.entity_id, "not_home") else (state_attr(trigger.entity_id, "target_temp") | int) }}"
- condition: template
value_template: >-
{{ state_attr(trigger.entity_id, "fan_speed") != None }}
sequence:
- service: fan.set_speed
data:
entity_id:
- fan.living_room
- fan.guest_room
# Not bothering to reset when they leave
speed: "{{ state_attr(trigger.entity_id, "fan_speed") | int }}"
- condition: template
value_template: >-
{{ state_attr(trigger.entity_id, "window_coverings") != None }}
sequence:
- service: "cover.{{ 'close' if is_state(trigger.entity_id, 'not_home') else state_attr(trigger.entity_id, "window_coverings") }}_cover
data:
entity_id:
- cover.living_room_blinds
- cover.family_room_blinds
default: []
Summarizing the Configuration Above
The example presented is fairly basic, covering only one preference per person. If the guest has a temperature preference it will adjust the thermostat, if the guest has a preference on air circulation it will adjust the specified fans to meet their request, if they have a preference for the blinds to be open it will open the specified blinds. When they leave, it returns to original state.
Definition of Done
- ✓ : Guests can specify a preferred temperature or fan settings
- ✓ : Climate adjusts when a guest with preferred climate settings arrives
- ✓ : Climate reverts back when guest with preferred climate settings departs
Stretch Goals
If you like the ideas presented in the cards above under stretch goals, or can think of other improvements over the ecobee, I challenge you to implement your solution and share it with the world!