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.
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.
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 %}
In addition, one thing I’ve found is that using the automation workflow seems easier to debug and prototype with. Primarily because its trivial to trigger the automation manually (for testing purposes) using the “Run Actions” button.
Whereas with template sensors its not so easy to fire the trigger condition and thereby update the sensor value.