this post was submitted on 09 Oct 2024
1 points (100.0% liked)

Home Assistant

459 readers
1 users here now

Home Assistant is open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY...

founded 1 year ago
MODERATORS
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/homeassistant by /u/kard87 on 2024-10-08 16:50:14+00:00.


I wanted to share an automation I've been working on:

Problem:

I have an Ecobee thermostat and wanted to adjust heating and cooling linearly based on how far the nearest household member is. My home is stone masonry and has a lot of thermal mass, so if I've been away for a while it can take 90+ minutes to get to the target temp, thus I want my HVAC to kick on as soon as I land at the airport for example (10 mi away). Originally, I had several zones set up but it was clunky so I wanted something cleaner.

Desired Behavior:

When the nearest household member is 10 miles away, the thermostat will fully be in its "away" mode (62-87). The thermostat will adjust linearly as I get closer till it's at the target home temps (70-73). Further, I want to set the HVAC mode based on outdoor temperature: if it's over 70 degrees set it to cool, under 50 set it to heat, in-between set it to auto heat_cool with a range of 69-74 (Ecobee minimum differential for the heat_cool mode is 5 degrees).

Prerequisite:

I use the Proximity integration and based everything on the nearest device, this is not needed if you live alone. Further, you need a way to get the outdoor temperature (I'm using Pirate Weather since I don't have a physical sensor but that would probably be a better way). You can also ignore the "season" aspect to simplify it and just leave it on auto heat_cool mode.

Solution:

First I created some Template Sensors to tell me:

  1. the current "season" (summer if over 70, winter if under 50, transition if in-between),
  2. the target heating temperature, and
  3. the target cooling temperature.

I created a sensors.yaml file with the following and put template: !include sensors.yaml in my config.yaml:

- sensor:
  - name: "Current Season"
    unique_id: current_season
    state: >
      {% set outdoor_temp = state_attr('weather.pirateweather', 'temperature')|float %}
      {% if outdoor_temp < 50 %}
        'winter'
      {% elif outdoor_temp > 70 %}
        'summer'
      {% else %}
        'transition'
      {% endif %}
  - name: "Desired Heating Temperature"
    unit_of_measurement: "°F"
    unique_id: sensor.desired_heating_temperature
    state: >
      {% if state_attr('weather.pirateweather', 'temperature')|float < 50 %}
        {% set min_heat_temp = 62 %}
        {% set max_heat_temp = 70 %}
      {% else %}
        {% set min_heat_temp = 62 %}
        {% set max_heat_temp = 69 %}
      {% endif %}
      {% set max_distance = 50000 %}
      {% set distance = states('sensor.home_nearest_distance')|float %}
      {% if distance > max_distance %}
        {{ min_heat_temp }}
      {% else %}
        {{ ((max_heat_temp - min_heat_temp) * (1 - (distance / max_distance)) + min_heat_temp)|round(0) }}
      {% endif %}
  - name: "Desired Cooling Temperature"
    unit_of_measurement: "°F"
    unique_id: sensor.desired_cooling_temperature
    state: >
      {% if state_attr('weather.pirateweather', 'temperature')|float > 70 %}
        {% set min_cool_temp = 73 %}
        {% set max_cool_temp = 87 %}
      {% else %}
        {% set min_cool_temp = 74 %}
        {% set max_cool_temp = 87 %}
      {% endif %}
      {% set max_distance = 50000 %}
      {% set distance = states('sensor.home_nearest_distance')|float %}
      {% if distance > max_distance %}
        {{ max_cool_temp }}
      {% else %}
        {{ ((min_cool_temp - max_cool_temp) * (1 - (distance / max_distance)) + max_cool_temp)|round(0) }}
      {% endif %}

I originally tried to use sensor.current_season in my other Template Sensors but it wasn't working, I assume they don't evaluate sequentially but not sure if that was the reason or if I didn't format it correctly. Next, I set up the automation as follows:

alias: Adjust Thermostat on Proximity and Season
triggers:
  - trigger: state
    entity_id:
      - sensor.desired_cooling_temperature
      - sensor.desired_heating_temperature
      - sensor.current_season
conditions:
  - condition: time
    after: "06:00:00"
    before: "23:30:00"
actions:
  - choose:
      - conditions:
          - condition: state
            entity_id: sensor.current_season
            state: "'summer'"
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_hvac_mode
            data:
              hvac_mode: cool
            target:
              entity_id: climate.thermostat
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_temperature
            data:
              temperature: "{{ states('sensor.desired_cooling_temperature') | float }}"
            target:
              entity_id: climate.thermostat
      - conditions:
          - condition: state
            entity_id: sensor.current_season
            state: "'winter'"
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_hvac_mode
            data:
              hvac_mode: heat
            target:
              entity_id: climate.thermostat
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_temperature
            data:
              temperature: "{{ states('sensor.desired_heating_temperature') | float }}"
            target:
              entity_id: climate.thermostat
      - conditions:
          - condition: state
            entity_id: sensor.current_season
            state: "'transition'"
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_hvac_mode
            data:
              hvac_mode: heat_cool
            target:
              entity_id: climate.thermostat
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - action: climate.set_temperature
            data:
              target_temp_low: "{{ states('sensor.desired_heating_temperature') | float }}"
              target_temp_high: "{{ states('sensor.desired_cooling_temperature') | float }}"
            target:
              entity_id: climate.thermostat
mode: restart

Few notes about my implementation:

  • I added a time condition as I have another automation to set it to Sleep Mode from 11:30 p.m. till 6 a.m. that I did not want to interfere with.
  • I had to format it state: "'summer'" under the conditions for the actions and no other format worked. I'm assuming I messed up how I defined the current_season sensor so if anyone knows what I did wrong let me know, but the above does work.
  • I originally had 1 action that set the HVAC mode and the temperature in the same step, but I had issues, so I split it as 2 separate actions (first set mode, then temp). I'm using the Homekit Integration for my Ecobee, not sure if it's a bug or not.
  • I set the mode to restart and added some delays as I noticed some race conditions. The automation triggers multiple times quickly when the sensors startup or when it changes seasons, so the delays and letting it restart assures it executes once when all the sensors have settled to the correct state.

I'm still testing but so far it seems to be functioning well, wanted to share with anyone that might be looking to do something similar or if anyone had any thoughts or potential improvements. My plan is to evaluate this for a week and adjust as needed, but hoping this could save someone some time that might be looking for a similar solution.

no comments (yet)
sorted by: hot top controversial new old
there doesn't seem to be anything here