Automation VS. trigger-based template

I’m using a door/window sensor in a rain gauge, so I’m trying to convert the open/close events into an accumulating value, plus do some extra things like keep the amount of rain that fell yesterday in a value as well.

Currently I’m doing this in a trigger-based template, but I’m finding this extremely limited, hard to work with and just an overal PITA. I know I can do everything in an automation, and have it be a lot more user friendly, but that left me wondering why all suggestions pointed to a trigger-based template and not an automation.

So, is there any downside to using an automation vs a TBT? I’d assume there’s more overhead, but that’s just that, an assumption.

Trigger based templates can retain values in their states and attributes. Automations don’t have this.

Since you are trying to create a sensor that has a state then a template based sensor makes sense.

I don’t think OP was suggesting that the automation holds the value, the automation sets the value of a helper via a service call. The helper holds the value. This is how it was commonly done prior to the introduction, just a couple years ago, of trigger-based Template sensors that survived restart.

I think it’s mostly down to personal preferences… Some users want their automations list to be compact and organized, so they don’t like having “uni-tasker” automations cluttering up their list. Some don’t like the idea of creating 2 entities when you can do it with one. Others just prefer setting up the conditional logic with templating rather than in YAML or the UI editor.

One practical benefit of template sensors is that their attributes aren’t as limited. They allow you to keep related data together in a single entity by using user-defined attributes which can be templated or static values. LIkewise, they are often more configurable, allowing you to define attributes like device class, state class, etc which aren’t normally available to helpers.

Well that’s the theory. I personally found the template sensor extremely limiting, but that may be my lack of experience with yaml and all the options that if does offer. I set up more functionality as an automation in 30 minutes than I was able to achieve in multiple days working on the template sensor. For some reason, my template sensor just went into state unknown and refused to get out of it. For me, currently, an automation with the Variables+History HACS addon is the way to go. You get total freedom on handling everything, and can still store everything in one variable, since it also support attributes. I don’t love relying on HACS addons, but if it works, it works.

Alright, since I have a hard time leaving things in the unknown, I want to understand template sensors. Like I said though, having a hard time. This is what I currently got, which is trimmed down:

template:
  - trigger:
    - id: count
      platform: state
      entity_id: "binary_sensor.aqara_dw_2_open_closed"
    - id: midnightReset
      platform: time
      at: "00:00:00"
    - id: resetFlips
      platform: state
      entity_id: sensor.zigbeerainmeter_test
      attribute: RainYesterday
      to:
    - id: onSevenDayArrayChange
      platform: state
      entity_id: sensor.zigbeerainmeter_test
      attribute: SevenDayArray
      to:
    - id: count
      platform: event
      event_type: "count"
    - id: midnightReset
      platform: event
      event_type: "midnightReset"
    sensor:
      - name: 'ZigbeeRainMeter TEST'
        unique_id: "zrm_test"
        state_class: measurement # only include this if you want long term statistics 
        device_class: precipitation
        unit_of_measurement: mm
        state: "1"
        attributes:
          Flips: "1"

Even this, without any calculations, results in an unknown state, and no attribute. The beauty is that there are no errors and the yaml syntax is valid. This is why I struggle with yaml, it’s just hard to debug due to the lack of proper error messages.

So, what am I doing wrong here?

A trigger needs to fire in order for the state template to be rendered… a value of unknown at restart is normal for a new or newly-updated sensor.

That makes sense, I probably expected that it would run once on creation so it would show an initial value or something like that. It could also be that I was confusing unknown with unavailable, since that’s what I’m running into now.

template:
  - trigger:
    - id: count
      platform: state
      entity_id: "binary_sensor.aqara_dw_2_open_closed"
    - id: midnightReset
      platform: time
      at: "00:00:00"
    - id: resetFlips
      platform: state
      entity_id: sensor.zigbeerainmeter_test
      attribute: RainYesterday
    - id: onSevenDayArrayChange
      platform: state
      entity_id: sensor.zigbeerainmeter_test
      attribute: SevenDayArray
    - id: count
      platform: event
      event_type: count
    - id: midnightReset
      platform: event
      event_type: midnightReset
    sensor:
      - name: 'ZigbeeRainMeter TEST'
        unique_id: "zrm_test"
        state_class: measurement # only include this if you want long term statistics 
        device_class: precipitation
        unit_of_measurement: mm
        state: >
          {{ this.attributes.Flips | float(0) * (states("sensor.aqara_rain_meter_rainfall_per_tick") | float) }}
        attributes:
          RainYesterday: >-
            {% if trigger.id == "midnightReset" %}
              {{ '%0.1f' | format(this.state) ~ " mm" }}
            {% endif %}
          Flips: >-
            {% if trigger.id == "count" %}
              {{ this.attributes.Flips | float(0) + 1 }}
            {% elif trigger.id == "resetFlips" %}
              0
            {% endif %}
          SevenDayArray: >-
            {% if trigger.id == "midnightReset" %}
              {% set sevenDayArray = state_attr('sensor.zigbeerainmeter_test', 'SevenDayArray') %}
              {% if sevenDayArray is not string %}
                sevenDayArray = "0;0;0;0;0;0;0"
              {% endif %}
              {{
                ([states('sensor.zigbeerainmeter_test') | round(2)] +
                sevenDayArray.split(';')[0:6]) |
                join(';')
              }}
            {% endif %}
          RainLastSevenDays: >-
            {% if trigger.id == "onSevenDayArrayChange" %}
              {% set total = namespace(a = 0) %}

              {% for value in state_attr('sensor.zrs_variables', 'SevenDayArray').split(';') %}
                {% set total.a = total.a + value | float %}
              {% endfor %}

              {{ '%0.1f' | format(total.a) ~ " mm" }}
            {% endif %}

With this code, I get unknown after reloading/restarting, and unavailable as soon as on of the triggers trigger. I tried the code from my previous post (state: 1, attribute Flips: 1). If an event triggers there, both values show up. If I put the above code in and reload, the count event works, but the midnightReset event makes it turn unavailable. No matter what I do after that, I can’t get it back to a working state. Reloading or restarting both don’t work, the only thing that works is going back to the basic values in my previous post.

Since there seems to be no debugging at all in yaml, how on earth do you figure out what’s causing this?

All of the attributes are evaluated on every trigger, and when not provided an else for what to do when the other triggers fire the if/then returns nothing.

RainYesterday: >-
  {% set current = this.attributes.RainYesterday if this is defined else none %}
  {% if trigger.id == "midnightReset" %}
    {{ '%0.1f' | format(this.state) ~ " mm" }}
  {% else %} 
    {{ current }}
  {% endif %}
1 Like