Trigger automation based on dynamically created sensors

I’d like to use HA to notify me if one of my ZPOOLs in my storage server goes bad. I’ve created a small python script that sends a notification of the pool status to my HA server on a regular interval via the API integration. This in turn creates a sensor for each pool with all relevant information as attributes. So far, so good.

Now I want to create a single automation that triggers off the attribute health for any of those sensors WITHOUT having to manually add the sensor for each pool. The sensors are all named sensor.zpool_xxx where xxx is the actual pool name.

Surely there must be a way to have an automation trigger on all state changes where the attribute type is “zpool” or where the name contains “zpool_”? I’m thinking that the template trigger should be able to do this but I can’t wrap my head around how to craft such a trigger.

Any suggestions?

This will return a list with all of your sensors:

{{ states.sensor | selectattr('entity_id', 'match', 'sensor.zpool_') | map(attribute='entity_id') | list }}

This will return a list of entities that have a specific state (in this case unavailable):

{{ states.sensor 
| selectattr('entity_id', 'match', 'sensor.zpool_') 
| selectattr('state', 'eq', 'unavailable')
| map(attribute='entity_id') 
| list 
}}

And finally this will provide all of your sensors with the health attribute in a state (in this case, “GOOD”):

{{ states.sensor 
| selectattr('entity_id', 'match', 'sensor.zpool_') 
| selectattr('attributes.health', 'defined')
| selectattr('attributes.health', 'eq', 'GOOD')
| map(attribute='entity_id') 
| list 
}}

I’m pretty sure you can use a trigger like this (I cannot test it right now):

trigger:
  - platform: template
    value_template: >-
      {{ states.sensor 
      | selectattr('entity_id', 'match', 'sensor.zpool_') 
      | selectattr('attributes.health', 'defined')
      | selectattr('attributes.health', 'eq', 'GOOD')
      | map(attribute='entity_id') 
      | list 
      | count
      > 0
      }}

The Template Trigger example you posted will trigger when the count of selected entities is above zero.

However, if the count continues to increase, it won’t trigger again. The count would first have to decrease to zero, thereby causing the template to report false, and then increase above zero to cause it re-trigger. It’s the template’s change from false to true that causes triggering.


I believe it may work if you simply make the template produce a count (remove the comparison to zero). If I’m not mistaken, a Template Trigger that produces a numeric value will trigger every time the value changes (this is based on a foggy recollection and not on recent testing). A condition can be used to check if the value is above zero.

1 Like

Thanks!

Seems a bit more complicated than I expected but I think I can work with this. I’ll have to do some testing tomorrow.

Yeah! That makes sense.
Thanks for adding.

So, there is:

trigger:
  - platform: template
    value_template: >-
      {{ states.sensor 
      | selectattr('entity_id', 'match', 'sensor.zpool_') 
      | selectattr('attributes.health', 'defined')
      | selectattr('attributes.health', 'eq', 'GOOD')
      | map(attribute='entity_id') 
      | list 
      | count
      }}

In fact it isn’t that complicated. Try to share your automation using just one of the existing sensors and we probably will be able to contribute to make it generic.

So I guess I can’t sleep tonight, so I did some more tinkering. I came to realize that I was going about this the wrong way. Keeping the data for my pools in sensors is nice for display, but for notifying me when something breaks, events are the way to go. So I simply added another call to the HA API that sends an event with the status right after updating the sensor values. Then I use the following as my automation:

alias: ZPOOL notification
description: ''
trigger:
  - platform: event
    event_type: ZPOOL_STATUS_EVENT
condition:
  - condition: template
    value_template: '{{ trigger.event.data.health != "AVAILABLE" }}'
action:
  - service: notify.mobile_app_ulduar
    data:
      title: ZPOOL event
    data_template:
      message: '{{ trigger.event.data.name }} is now {{ trigger.event.data.health }}'
  - service: automation.turn_off
    data:
      stop_actions: false
    target:
      entity_id: automation.zpool_degradation_notification
mode: single

I might add another automation to re-enable this one but I think a single notification will be enough - anytime a pool has an issue it will have to be dealt with ASAP anyhow…