Automation trigger based on sensor.openweathermap_uv_index

Hi,

I am trying to define an automation to set the position of our 3 shutters of our roof-top-windows.
I successfully defined 6 scripts to set different positions : Shelly 2 roller shutter tilt - #2 by schneich (-> open, 33%, 50%, 66%, closed)

Right now, I am struggling with the trigger. Unfortunately, I do not (yet) have a temperature sensor in that room, so I wanted to base the trigger on sensor.openweathermap_uv_index.
Something like this:

  • UV-idex < 4 = open
  • 4 < UV-index < 4.5 = 33% closed

As trigger, I tried with a numeric-state-trigger, but that did not work. So I changed to template-trigger. It seemed to work at first, but not anymore. When I check the template within the developer tools, all looks good.

Is this the right way to approach this?

alias: Dach Rollo Management
description: |-
  based on UV-Index shutter will be closed step-by-step.
  0-4.0 -> nothing
  4.0-4.5 -> 1/3 closed
  4.5-5.0 -> 50% closed
  5.0-6.0 -> 2/3 closed
  6.0+ -> 100% closed
trigger:
  - platform: template
    value_template: |-
      {% if 4.5 > states('sensor.openweathermap_uv_index')|float(0) >= 4 %} 
        true
      {% else %}
        false
      {% endif %}
    for: '00:15:00'
  - platform: template
    value_template: |-
      {% if 5.0 > states('sensor.openweathermap_uv_index')|float(0) >= 4.5 %} 
        true
      {% else %}
        false
      {% endif %}
    for: '00:15:00'
  - platform: template
    value_template: |-
      {% if 6.0 > states('sensor.openweathermap_uv_index')|float(0) >= 5.0 %} 
        true
      {% else %}
        false
      {% endif %}
    for: '00:15:00'
  - platform: template
    value_template: |-
      {% if states('sensor.openweathermap_uv_index')|float(0) >= 6.0 %} 
        true
      {% else %}
        false
      {% endif %}
    for: '00:15:00'
  - platform: template
    value_template: |-
      {% if states('sensor.openweathermap_uv_index')|float(0) < 4 %} 
        true
      {% else %}
        false
      {% endif %}
    for: '00:00:15'
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: |-
              {% if not is_number(states('sensor.openweathermap_uv_index')) %}
                true
              {% else %}
                false
              {%endif%}
        sequence:
          - stop: UV-Index is not a number.
            error: true
      - conditions:
          - condition: template
            value_template: >-
              {% if 4.5 > states('sensor.openweathermap_uv_index')|float(0) >= 4
              %} 
                true
              {% else %}
                false
              {% endif %}
        sequence:
          - service: script.dach_rollos_33_zu
            data: {}
      - conditions:
          - condition: template
            value_template: >-
              {% if 5.0 > states('sensor.openweathermap_uv_index')|float(0) >=
              4.5 %} 
                true
              {% else %}
                false
              {% endif %}
        sequence:
          - service: script.dach_rollos_50_zu
            data: {}
      - conditions:
          - condition: template
            value_template: >-
              {% if 6.0 > states('sensor.openweathermap_uv_index')|float(0) >=
              5.0 %} 
                true
              {% else %}
                false
              {% endif %}
        sequence:
          - service: script.dach_rollos_66_zu
            data: {}
      - conditions:
          - condition: template
            value_template: |-
              {% if states('sensor.openweathermap_uv_index')|float(0) >= 6.0 %} 
                true
              {% else %}
                false
              {% endif %}
        sequence:
          - service: script.dach_rollos_zu
            data: {}
    default:
      - service: script.dach_rollos_auf
        data: {}
mode: single

[EDIT: language translation within code]

Does it only trigger once? What is the symptom?

I think because all the triggers are ALWAYS true, your automation will only run once. I’ve not fiddled with template triggers so not sure.

I would try a state trigger - which is effectively what you are trying to do:

  trigger:
    - platform: state
      entity_id:
        - sensor.openweathermap_uv_index

This will trigger every time your sensor gets a new value.

1 Like

Also if you want a true/false result there’s no need to use if/else. The mathematical tests > < == != will return true or false. So this:

            value_template: >-
              {% if 4.5 > states('sensor.openweathermap_uv_index')|float(0) >= 4
              %} 
                true
              {% else %}
                false
              {% endif %}

Can be simplified to:

            value_template: >
              {{ 4.5 > states('sensor.openweathermap_uv_index')|float(0) >= 4 }}

Try it in the template editor.

Some more suggestions:

You can use trigger IDs and variables so that you don’t need to repeat (all) the tests in the choose conditions. For example, you can assign each trigger a unique ID using the script names, since they’re unique, and then use that ID when you call the script.

You can also change your script to accept parameters instead of having a script for each value.

Lastly, you can test what happens if you call cover.open and/or cover.close with 0% and 100% respectively. I only have covers (doors) where I know whether they’re open or closed and no position, but I know that with lights, if you call light.turn_on with 0 brightness, the light will turn off.

I think replacing the trigger with Daryl’s suggestion is best.

Yes, you’re probably right. I thought, given the cover positions OP selected, that they didn’t want constant/continuous updates to the cover controller (I think OWM updates every 15 min). I vaguely remember people worrying about burning out the motor with constant updates, but I guess, if like in this case only a handful of positions are used and the controller don’t react if a given position is already set, that worry isn’t valid.

@zoogara, @tom_l, @parautenbach

Thank you very much for your valuable inputs.

I implemented the state trigger, which works perfectly fine. Especially, as the sensor.openweathermap_uv_index provides new date every 60min. So no worries about having shutters going up and down every other minute…

Question:
In my first version with the template triggers, I was assuming that the template was calculated with every change in the sensor. I was assuming that as long as the value stays within the range, nothing changes. As soon as the input value form the sonsor slides into the next range, the automation should trigger.
Is this assumption wrong?
In the future, I want to switch form UV-index to an internal temperature sensor. This will provide new data every other minute. How do I stop the automation to trigger, when the temp-values are just hopping around - lets say 24°C? (Assuming 24°C is a defined threshhold.)

@tom_l Can be simplified to:

             {{ 4.5 > states('sensor.openweathermap_uv_index')|float(0) >= 4 }}

Thank you very much for that input. I did try it with
{% 4.5 > states(‘sensor.openweathermap_uv_index’)|float(0) >= 4 %}

I am playing oround with HomeAssistant for almost a year. I am not a professional coder. I do have some experience with JavaScript, Groovy and the Arduino IDE (-> C+?). But the HomeAssistant syntax is not that easy to get my head around. The documentation is extensive, but nothing a poor beginner could work with.
Is there an explanation, when to use {{ … }} and when to use {% … %}?

Chris

No, you are correct, but…

You weren’t triggering on the sensor. You were triggering on a template. Because of your logic in the trigger, it ALWAYS evaluated to TRUE. Thus after the first triggering the value never changed and this it never ran the automation again.

I should leave this for Tom to answer but it’s early here so I’ll probably beat him to it :slight_smile: - essentially:

There are a few kinds of delimiters. The default Jinja delimiters are configured as follows:

Templates are based on Jinja2, the above is from the documentation site.