Automation Blueprint not working

Hi all,

after nearly 2 weeks of reading, fixing, reading and fixing again, I want to try my luck here…

After a lot (I really mean A LOT) of troubleshooting, I finally wanted to create my own heating automation for my Aqara E1 TRVs. I managed to create a blueprint that creates an automation. However, I cannot get this automation to run.

My troubleshooting so far makes me believe, that something is wrong with the use of variables in my blueprint. If I create an automation with this blueprint, and I test the if conditions, all of them using variables seem to fail. But whatever I try, I cannot get it to work. I read so lot about blueprints, triggers, actions, inputs, variables and so on, but I have to admit that I have now reached the end of my knowledge.

I really hope someone can point me in the right direction… even ChatGPT and Gemini gave up already :smiley:

This is my blueprint so far:

blueprint:
  name: "\U0001F525 Aqara E1 Heating"
  author: veniplex
  homeassistant:
    min_version: 2024.9.3
  description: "Set the current temperature on an Aqara E1 TRV from an external sensor."
  domain: automation
  
  ### INPUTS
  input:
    radiator_section:
      name: "Radiator"
      icon: mdi:thermostat
      input:
        radiator:
          name: "Aqara E1 Device"
          description: "`climate`\n\nSelect the Aqara E1 device to be controlled."
          selector:
            entity:
              multiple: false
              filter:
                - integration: mqtt
                  domain: climate
    thermostat_section:
      name: Thermostats
      icon: mdi:thermometer
      input:
        room_thermostat:
          name: Room Thermostat
          description: "`sensor`\n\nSelect the thermostat that measures the temperature in the room."
          selector:
            entity:
              multiple: false
              filter:
                - domain: sensor
                  device_class: temperature
        outside_thermostat:
          name: Outside Thermostat
          description: "`sensor`\n\nSelect the thermostat (or `sensor` from a weather integration) that measures the outside temperature for your location."
          selector:
            entity:
              multiple: false
              filter:
                - domain: sensor
                  device_class: temperature
    temperature_section:
      name: Temperatures
      icon: mdi:home-thermometer-outline
      input:
        temperature_antifreeze:
          name: "Static Frost Protection Temperature"
          description: "`input_number`\n\nSet the minimum temperature to prevent the heaters from freezing (Recommended: min. 8 °C)."
          default: 8
          selector:
            number:
              min: 5
              max: 30
              unit_of_measurement: "°C"
              mode: slider
        temperature_antifreeze_helper:
          name: "Frost Protection Temperature Helper"
          description: "`input_number`\n\nSet the minimum temperature to prevent the heaters from freezing via a helper entity. This allows you to change the temperature from your dashboard. If no helper entity is selected, the static frost protection temperature will be used."
          default:
          selector:
            entity:
              multiple: false
              filter:
                - domain: input_number
        temperature_eco:
          name: "Static Eco Temperature"
          description: "`input_number`\n\nSet the eco temperature to use when e.g. no one is at home (Recommended: 16 - 18 °C)."
          default: 18
          selector:
            number:
              min: 5
              max: 30
              unit_of_measurement: "°C"
              mode: slider
        temperature_eco_helper:
          name: "Eco Temperature Helper"
          description: "`input_number`\n\nSet the eco temperature to use when e.g. no one is at home. This allows you to change the temperature from your dashboard. If no helper entity is selected, the static eco temperature will be used."
          default:
          selector:
            entity:
              multiple: false
              filter:
                - domain: input_number
        temperature_comfort:
          name: "Static Comfort Temperature"
          description: "`input_number`\n\nSet the comfort temperature to use when e.g. someone is at home (Recommended: 18 - 22 °C)."
          default: 22
          selector:
            number:
              min: 5
              max: 30
              unit_of_measurement: "°C"
              mode: slider
        temperature_comfort_helper:
          name: "Comfort Temperature Helper"
          description: "`input_number`\n\nSet the comfort temperature to use when e.g. someone is at home. This allows you to change the temperature from your dashboard. If no helper entity is selected, the static comfort temperature will be used."
          default:
          selector:
            entity:
              multiple: false
              filter:
                - domain: input_number
        temperature_outside:
          name: "Static Outside Temperature"
          description: "`input_number`\n\nSet the outside temperature at which the radiator should be set to frost protection or turned off (see advanced settings)."
          default: 22
          selector:
            number:
              min: 5
              max: 30
              unit_of_measurement: "°C"
              mode: slider
        temperature_outside_helper:
          name: "Outside Temperature Helper"
          description: "`input_number`\n\nSet the outside temperature at which the radiator should be set to frost protection or turned off (see advanced settings). This allows you to change the target temperature from your dashboard. If no helper entity is selected, the static outside temperature will be used."
          default:
          selector:
            entity:
              multiple: false
              filter:
                - domain: input_number
    schedule_section:
      name: Schedules
      icon: mdi:clock-outline
      input:
        schedule_eco:
          name: Eco Schedule
          description: "`schedule`\n\nSelect a schedule for heating to eco temperature."
          selector:
            entity:
              multiple: false
              filter:
                - domain: schedule
        schedule_comfort:
          name: Comfort Schedule
          description: "`schedule`\n\nSelect a schedule for heating to comfort temperature."
          selector:
            entity:
              multiple: false
              filter:
                - domain: schedule
    presence_section:
      name: Presence
      icon: mdi:location-enter
      input:
        presence_person:
          name: "Person(s)"
          description: "`person`\n\nSelect one or more person entities to activate comfort heating only if someone is at home. Otherwise heat on eco temperature."
          default: []
          selector:
            entity:
              multiple: true
              filter:
                - domain: person
        presence_helper:
          name: "Presence Helper"
          description: "`input_boolean`\n\nSelect a helper entity of type `input_boolean` which represents the 'someone is at home' state. Make sure this helper is set to `on` if someone is at home and `off` if nobody is at home."
          default:
          selector:
            entity:
              multiple: false
              filter:
                - domain: input_boolean
    window_section:
      name: Window sensors
      icon: mdi:blinds-vertical
      input:
        window_windows:
          name: "Window(s)"
          description: "`binary_sensor`\n\nSelect one or more window sensors. These are used to decide if heating should be turned on or off."
          default: []
          selector:
            entity:
              multiple: true
              filter:
                - domain: binary_sensor
    advanced_section:
      name: Advanced Settings
      icon: mdi:tools
      collapsed: true
      input:
        advanced_frost_protection:
          name: "Frost Protection"
          description: "`boolean`\n\nEnable (default) or disable frost protection. This will always use the frost protection temperature instead of turning the radiator completley off."
          default: true
          selector:
            boolean:
        advanced_window_detection:
          name: Window Detection
          description: "`boolean`\n\nEnable or disable (default) the window detection on the Aqara E1 device. It is recommended to only activate this if no window sensors are set."
          default: false
          selector:
            boolean:
        advanced_child_lock:
          name: Child Lock
          description: "`boolean`\n\nEnable (default) or disable child lock on the Aqara E1 device. This prevents accidental manual changes on the radiator itself. It can be disabled manually on the radiator or in the entity settings."
          default: true
          selector:
            boolean:
        advanced_valve_detection:
          name: Valve Detection
          description: "`boolean`\n\nEnable (default) or disable valve detection on the Aqara E1 device. This allows the device to detect problems with adjusting the valve."
          default: true
          selector:
            boolean:
        # advanced_update_interval:
        #   name: "Update Interval"
        #   description: "`input_number`\n\nSet the interval (in minutes) to update the radiator settings and current temperatures, not target temperatures, so a manual change is still possible (Recommended: 15 minutes)."
        #   default: 15
        #   selector:
        #     number:
        #       min: 1
        #       max: 60
        #       unit_of_measurement: "minutes"
        #       mode: slider
        # advanced_calibration_interval:
        #   name: "Calibration Interval"
        #   description: "`input_number`\n\nSet the interval (in hours) to trigger a calibration on the radiator (Recommended: 168 hours / 7 days)."
        #   default: 23
        #   selector:
        #     number:
        #       min: 1
        #       max: 23
        #       unit_of_measurement: "hours"
        #       mode: slider
        advanced_window_opened_interval:
          name: "Windows Opened Interval"
          description: "`input_number`\n\nSet the interval (in seconds) to trigger at opened windows. (Recommended: 15 seconds)."
          default: 15
          selector:
            number:
              min: 1
              max: 60
              unit_of_measurement: "seconds"
              mode: slider
        advanced_window_closed_interval:
          name: "Windows Closed Interval"
          description: "`input_number`\n\nSet the interval (in seconds) to trigger at closed windows. (Recommended: 15 seconds)."
          default: 15
          selector:
            number:
              min: 1
              max: 60
              unit_of_measurement: "seconds"
              mode: slider

### VARIABLES
# see: https://www.home-assistant.io/docs/blueprint/schema/#blueprint-inputs-in-templates
trigger_variables:
  radiator: !input radiator
  room_thermostat: !input room_thermostat
  outside_thermostat: !input outside_thermostat
  temperature_antifreeze: !input temperature_antifreeze
  temperature_antifreeze_helper: !input temperature_antifreeze_helper
  temperature_eco: !input temperature_eco
  temperature_eco_helper: !input temperature_eco_helper
  temperature_comfort: !input temperature_comfort
  temperature_comfort_helper: !input temperature_comfort_helper
  temperature_outside: !input temperature_outside
  temperature_outside_helper: !input temperature_outside_helper
  presence_person: !input presence_person
  advanced_frost_protection: !input advanced_frost_protection
  advanced_window_detection: !input advanced_window_detection
  advanced_child_lock: !input advanced_child_lock
  advanced_valve_detection: !input advanced_valve_detection
  advanced_window_opened_interval: !input advanced_window_opened_interval
  advanced_window_closed_interval: !input advanced_window_closed_interval

### TRIGGERS
triggers:
  # Trigger the automation at specified intervals for updates
  - trigger: time_pattern
    minutes: '/15'
    alias: "Update temperature on radiator every 15 minutes"
    id: "trigger_temperature"
  - trigger: template
    value_template: >
      {{ now().day % 7|int == 0 }}
    alias: "Calibrate radiator every 7 days"
    id: "trigger_calibration"
  # Trigger when any window sensor changes to open (on)
  - trigger: state
    entity_id: !input window_windows
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: !input advanced_window_opened_interval
    alias: "A window was opened"
    id: "trigger_all"
  # Trigger when any window sensor changes to close (off)
  - trigger: state
    entity_id: !input window_windows
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: !input advanced_window_closed_interval
    alias: "A window was closed"
    id: "trigger_all"
  # Trigger when someone enters home
  - trigger: zone
    entity_id: !input presence_person
    zone: zone.home
    event: enter
    id: "trigger_all"
  # Trigger when someone leaves home
  - trigger: zone
    entity_id: !input presence_person
    zone: zone.home
    event: leave
    id: "trigger_all"
  # Trigger when automations are reloaded
  - trigger: event
    event_type:
      - automation_reloaded
      - core_config_updated
    alias: "The automation was reloaded or config was changed"
    id: "trigger_all"
  # Trigger when Home Assistant is started
  - trigger: homeassistant
    event: start
    alias: "Home Assistant was started"
    id: "trigger_all"

variables:
  temperature_antifreeze_calculated: "{{ (temperature_antifreeze_helper | default(temperature_antifreeze)) | float }}"
  temperature_eco_calculated: "{{ (temperature_eco_helper | default(temperature_eco)) | float }}"
  temperature_comfort_: "{{ (temperature_comfort_helper | default(temperature_comfort)) | float }}"
  temperature_outside_calculated: "{{ (temperature_outside_helper | default(temperature_outside)) | float }}"

### CONDITIONS
conditions: []

### ACTIONS
actions:
  - sequence:
    - if:
        - condition: trigger
          id: "trigger_all"
      then:
        - alias: "Wenn die Außentemperatur höher als die Außen-Zieltemperatur ist..."
          if:
            - condition: template
              value_template: "{{ states(outside_thermostat) | float >= temperature_outside_calculated | float }}"
          then:
            - alias: "Und 'advanced_frost_protection' ist auf 'true' gesetzt ist..."
              if:
                - condition: template
                  value_template: "{{ is_state(advanced_frost_protection, 'true') }}"
              then:
                - alias: "Dann stelle die Heizung auf Frost-Protection-Temperatur"
                  action: climate.set_temperature
                  metadata: {}
                  data:
                    temperature: "{{ temperature_antifreeze_calculated | float }}"
                  target:
                    entity_id: !input radiator
                - alias: "Und auf heizen."
                  action: climate.set_hvac_mode
                  target:
                    entity_id: !input radiator
                  data:
                    hvac_mode: heat
              else:
                - alias: "Sonst schalte die Heizung aus."
                  action: climate.set_hvac_mode
                  target:
                    entity_id: !input radiator
                  data:
                    hvac_mode: off
        - alias: "Wenn die Außentemperatur niedriger als die Außen-Zieltemperatur ist..."
          if:
            - condition: template
              value_template: "{{ states(outside_thermostat) | float < temperature_outside_calculated | float }}"
          then:
          - alias: "Und der Komfortzeitplan eingeschaltet ist..."
            if:
              - condition: state
                entity_id: !input schedule_comfort
                state: "on"
            then:
              - alias: "Und jemand ist zuhause..."
                if:
                  - condition: or
                    conditions:
                    - condition: state
                      entity_id: !input presence_person
                      state: "home"
                    - condition: state
                      entity_id: !input presence_helper
                      state: "on"
                then:
                  - alias: "Und alle Fenster geschlossen sind..."
                    if:
                      - condition: state
                        entity_id: !input window_windows
                        state: "off"
                    then:
                      - alias: "Dann stelle die Heizung auf Komfort-Temperatur"
                        action: climate.set_temperature
                        metadata: {}
                        data:
                          temperature: "{{ temperature_comfort_calculated | float }}"
                        target:
                          entity_id: !input radiator
                      - alias: "Und auf heizen."
                        action: climate.set_hvac_mode
                        target:
                          entity_id: !input radiator
                        data:
                          hvac_mode: heat
                    else:
                      - alias: "Sonst, wenn 'advanced_frost_protection' ist auf 'true' gesetzt ist..."
                        if:
                          - condition: template
                            value_template: "{{ is_state(advanced_frost_protection, 'true') }}"
                        then:
                          - alias: "Dann stelle die Heizung auf Frost-Protection-Temperatur"
                            action: climate.set_temperature
                            metadata: {}
                            data:
                              temperature: "{{ temperature_antifreeze_calculated | float }}"
                            target:
                              entity_id: !input radiator
                          - alias: "Und auf heizen."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: heat
                        else:
                          - alias: "Sonst schalte die Heizung aus."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: off
                else:
                  - alias: "Und alle Fenster geschlossen sind..."
                    if:
                      - condition: state
                        entity_id: !input window_windows
                        state: "off"
                    then:
                      - alias: "Dann stelle die Heizung auf Eco-Temperatur"
                        action: climate.set_temperature
                        metadata: {}
                        data:
                          temperature: "{{ temperature_eco_calculated | float }}"
                        target:
                          entity_id: !input radiator
                      - alias: "Und auf heizen."
                        action: climate.set_hvac_mode
                        target:
                          entity_id: !input radiator
                        data:
                          hvac_mode: heat
                    else:
                      - alias: "Sonst, wenn 'advanced_frost_protection' ist auf 'true' gesetzt ist..."
                        if:
                          - condition: template
                            value_template: "{{ is_state(advanced_frost_protection, 'true') }}"
                        then:
                          - alias: "Dann stelle die Heizung auf Frost-Protection-Temperatur"
                            action: climate.set_temperature
                            metadata: {}
                            data:
                              temperature: "{{ temperature_antifreeze_calculated | float }}"
                            target:
                              entity_id: !input radiator
                          - alias: "Und auf heizen."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: heat
                        else:
                          - alias: "Sonst schalte die Heizung aus."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: off
            else:
              - alias: "Sonst, wenn Eco-Zeitplan eingeschaltet ist..."
                if:
                  - condition: state
                    entity_id: !input schedule_eco
                    state: "on"
                then:
                  - alias: "Und alle Fenster geschlossen sind..."
                    if:
                      - condition: state
                        entity_id: !input window_windows
                        state: "off"
                    then:
                      - alias: "Dann stelle die Heizung auf Eco-Temperatur"
                        action: climate.set_temperature
                        metadata: {}
                        data:
                          temperature: "{{ temperature_eco_calculated | float }}"
                        target:
                          entity_id: !input radiator
                      - alias: "Und auf heizen."
                        action: climate.set_hvac_mode
                        target:
                          entity_id: !input radiator
                        data:
                          hvac_mode: heat
                    else:
                      - alias: "Sonst, wenn 'advanced_frost_protection' ist auf 'true' gesetzt ist..."
                        if:
                          - condition: template
                            value_template: "{{ is_state(advanced_frost_protection, 'true') }}"
                        then:
                          - alias: "Dann stelle die Heizung auf Frost-Protection-Temperatur"
                            action: climate.set_temperature
                            metadata: {}
                            data:
                              temperature: "{{ temperature_antifreeze_calculated | float }}"
                            target:
                              entity_id: !input radiator
                          - alias: "Und auf heizen."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: heat
                        else:
                          - alias: "Sonst schalte die Heizung aus."
                            action: climate.set_hvac_mode
                            target:
                              entity_id: !input radiator
                            data:
                              hvac_mode: off
      else:
        - alias: "Ansonsten, wenn die Automatisierung durch 'trigger_temperature' ausgelöst wurde..."
          if:
            - condition: trigger
              id: "trigger_temperature"
          then:
            # - alias: "Dann setze den Sensor am Radiator auf 'external'"
            #   action: mqtt.publish
            #   data:
            #     topic: "zigbee2mqtt/{{ state_attr(variables.radiator, 'friendly_name') }}/set"
            #     payload: '{"sensor": "external"}'
            # - alias: "Und setze die aktuelle Temperatur auf die Temperatur des Raumthermostats"
            #   action: mqtt.publish
            #   data:
            #     topic: "zigbee2mqtt/{{ state_attr(variables.radiator, 'friendly_name') }}/set"
            #     payload: '{"external_temperature_input": {{ states(variables.room_thermostat) }}}'
            - alias: "Setze den Radiator und zusätzliche Einstellungen"
              action: mqtt.publish
              data:
                topic: "zigbee2mqtt/{{ state_attr(radiator, 'friendly_name') }}/set"
                payload: >
                  {
                    "sensor": "external",
                    "external_temperature_input": {{ states(room_thermostat) }},
                    "child_lock": {{ is_state(advanced_child_lock, 'true') | lower }},
                    "window_detection": {{ is_state(advanced_window_detection, 'true') | lower }},
                    "valve_detection": {{ is_state(advanced_valve_detection, 'true') | lower }}
                  }
          else:
            - alias: "Ansonsten, wenn die Automatisierung durch 'trigger_calibration' ausgelöst wurde..."
              if:
                - condition: trigger
                  id: "trigger_calibration"
              then:
                - alias: "Dann Kalibriere den Radiator."
                  action: mqtt.publish
                  data:
                    topic: "zigbee2mqtt/{{ state_attr(radiator, 'friendly_name') }}/set"
                    payload: '{"calibrate": "calibrate"}'

Can you share a trace of an if statement that ‘fails’? Or show more specifically what step is not working?

1 Like

Hi ,
Well the good thing is that all the values you have plugged into variables in that blueprint you will be able to see the value of every one of them and pretty much figure out the problem. The bad thing is all those if statements. So easy to get lost in there. So easy to set a value in there and have it get killed by the value being set out of scope That’s where I would look, places where you set values that may get lost with scope.

As he said, a trace would be helpful.

1 Like

@karwosts
Yes of course. However, I am not 100% sure how to do this. What I can deliver is this:
Steps to reproduce:

  1. I set my language to english and the theme to the default Home Assistant theme.
  2. I created the blueprint .yaml inside the VSCode Extension under /config/blueprints/automation/veniplex/aqara_e1_heating.yaml.
  3. Then I created a new automation based on this blueprint via the UI.
  4. I took over control of the newly created automation.
  5. I can see, that different triggers are triggered, because once in a while I see the blue status bar at the top of the trigger saying TRIGGERED:
  6. If I now manually check one if condition, that works and must be false, I see this (as expected):
  7. If I now manually check one if condition, that dosn’t work and must be true, I see this (notice the difference in color - grey instead of orange - and the banner doesn’t disappear until a page refresh!):

Can I deliver anything else?

Btw: I also tried to use the action: logbook.log inside this automation (of course outside of every if statement), but it seemed not to work at all. The automation itself is always “stuck” at the state last triggered = never.

@Sir_Goodenough
Thank you for the hint. How can I check if my variables are within scope or not? Honestly, until now I thought there is only one global scope, which is variables: [] and the trigger-specific scope of trigger_variables: [], which evaluates the variables before the trigger is run.