So I had a similar situation once with my Nest thermostat, before the integration switched to stream based from polling based, although it still happens sometimes that a command does not take effect. And in my case the only command I send is to change the mode to/from “ECO” mode.
What I did was to write a script that would change the mode according to an input variable. It would then wait a while (long enough that the changes should have taken effect), and then it checks the state. If it’s correct, then it’s done. If not, then it effectively calls itself again. Later, when it happened much less often I simplified to where instead of trying again it simply sent me a text to tell me it happened.
Following is what I use today, starting with the automation that changes the mode when the house switches to/from “away”:
- alias: Nest Thermostat
trigger:
platform: state
entity_id: input_select.home_mode
condition:
condition: template
value_template: >
{{ trigger.from_state.state in ['Home', 'Returning'] and
trigger.to_state.state in ['Away'] or
trigger.from_state.state in ['Away'] and
trigger.to_state.state in ['Home', 'Returning'] }}
action:
- service: script.turn_off
entity_id:
- script.nest_eco_on
- script.nest_eco_off
- script.nest_eco_check
- service_template: >
{% if trigger.to_state.state in ['Away'] %}
script.nest_eco_on
{% else %}
script.nest_eco_off
{% endif %}
And here are the scripts:
nest_eco_on:
alias: Nest Thermostat - Set to ECO mode
sequence:
- wait_template: "{{ is_state('timer.nest_thm_wait', 'idle') }}"
# Only turn on ECO mode if thermostat is not off and not already in ECO
# mode.
- condition: template
value_template: >
{{ states('sensor.kitchen_thermostat_hvac_mode')
not in ['off', 'eco'] }}
# Save current operation mode.
- service: input_text.set_value
entity_id: input_text.previous_hvac_mode
data_template:
value: "{{ states('sensor.kitchen_thermostat_hvac_mode') }}"
- service: timer.start
entity_id: timer.nest_thm_wait
# Turn on ECO mode.
- service: climate.set_preset_mode
entity_id: climate.kitchen
data:
preset_mode: eco
- service: script.nest_eco_check
data:
eco_on: true
nest_eco_off:
alias: Nest Thermostat - Return from ECO mode
sequence:
- wait_template: "{{ is_state('timer.nest_thm_wait', 'idle') }}"
# Only set back to previous mode if thermostat is still in ECO mode.
- condition: template
value_template: >
{{ is_state('sensor.kitchen_thermostat_hvac_mode', 'eco') }}
- service: timer.start
entity_id: timer.nest_thm_wait
# Restore previous operation mode.
- service: climate.set_hvac_mode
entity_id: climate.kitchen
data_template:
hvac_mode: "{{ states('input_text.previous_hvac_mode') }}"
- service: script.nest_eco_check
data:
eco_on: false
nest_eco_check:
alias: Nest Thermostat - Check ECO mode
sequence:
# Wait for last command to take effect in state.
# Also wait until thermostat is online.
- wait_template: >
{{ is_state('timer.nest_thm_wait', 'idle') and
is_state('binary_sensor.kitchen_thermostat_online', 'on') }}
# Delay a bit for state to update in case thermostat was offline.
- delay: '00:02:00'
# Are we in the wrong mode?
- condition: template
value_template: >
{{ eco_on and
not is_state('sensor.kitchen_thermostat_hvac_mode', 'eco') or
not eco_on and
is_state('sensor.kitchen_thermostat_hvac_mode', 'eco') }}
- service: notify.email_phil
data:
title: 'Alert:'
message: ECO mode did not change
As I said, the “check” script used to call the turn on or off script again if it didn’t work, and I think I may have had a max counter or something so it didn’t go on forever.
Hope this helps.