Hi, I’m having a problem trying to get an automation to trigger based on ‘any’ entity_id that has a specific attribute set, without defining each individual entity_id as they will change too often and the whole system will be in the hands of a novice (even more novicey than me!).
Couldn’t figure which category to add this to
This is for the HACS Plant monitor Integration but it is not Integration specific.
I’m trying to achieve a situation where an Automation detects any Plant (plant.*) that has an attribute of conductivity_status set to ‘Low’ and then executes (Then Do…)
I’ve tried using templates but I can’t see how to add them in the entity_id field and omg, the syntax is literally doing me in. I keep coming up against the same problem, which is I can’t put a {% for %} statement inside an {% if %} loop, it’s safe to say I don’t understand templates very well.
Oh dear, I’ve just realised my problem is a little more difficult than I thought, since the field I want to test on is not an entity, but an attribute of an entity (defined by the Plant Monitor Integration based on whether the actual entity is higher or lower than the the actual entity_max or entity_min values…
This means the user has to be able to edit the automation, add the plant, select the attribute to test and type in the needed result (not from a pull-down choice) to trigger the event. Which is a little too much for my user (my niece).
If it were possible in any way to automatically populate the entity_id field, possibly with a template, I would be very grateful
Maybe this alternative plant integration can come to the rescue. It allows you to change which attributes determine if a plant is OK or not OK. Set that to conductivity and the range that corresponds with the plant. From then on you can create a group. It also comes with nice compatible plant database and plant card:
Thanks for the response, but I’m already using that alternative, it’s the thing that is calculating whether the individual levels are ‘OK’, ‘High’ or ‘Low’.
Because I’m using the HA Voice Preview, I want to respond to a question with all of the plants that have a ‘Low’ status and it’s not possible with my brain, to work out the syntax in a template to do that.
At the moment, I can respond to individual requests for ‘moisture_status’ and ‘conductivity_status’, but not both together, not without the whole thing erroring, since I can’t filter out “null” responses whilst also filtering out whether both states are ‘Low’.
Not sure I understand the question. If I use the below template I can get a list of all the plants that need feeding;
{% for state in states.plant if 'Low' in state.attributes.conductivity_status and 'Low' in state.attributes.moisture_status | replace('none', 'ok') -%}
{%- if loop.first %}the {% elif loop.last %}, and {% else %}, {% endif -%}
{{ state.name }}
{%- endfor %} needs feeding
If I use this next one I can get a list of all the ones that need watering;
{% for state in states.plant if 'Low' in state.attributes.moisture_status | replace('none', 'is not currently available') -%}
{%- if loop.first %}The {% elif loop.last %}, and {% else %}, {% endif -%}
{{ state.attributes.friendly_name }}
{%- endfor %} needs watering
but I have to respond in one template command in order to to get the HA Voice Preview to send the result or else it fails, so I can’t just put the two together, one after the other, in an automation, they have to be part of the same response.
My template skills or nowhere near good enough to work out how to do this so I’m asking more specific questions that I think will fix the issue.
In this case, I don’t want a list of all the plants that need feeding, just a test that any do, because if I use that template when no plants need feeding, it will still say “need feeding”, whereas I would like to if/else that automation so that it says “no plants need feeding” or nothing at all, if they don’t
So you need a sentence of all the plants that need feeding, or a nice text that no plants need feeding. That is not a trigger for an automation. A trigger is something happening, not a test you can use in an if.
Try this in the developer tools template tester:
{% set low = states.plant | selectattr('attributes.conductivity_status','eq','Low') | map(attribute='name') | list %}
{{ ('No plants' if low | count == 0 else low | join(', ')) ~ ' need watering' }}
Or, with help from Petro, the even nicer sentence for multiple plants:
{% set low = states.plant | selectattr('attributes.conductivity_status','eq','Low') | map(attribute='name') | list %}
{{ ([low[:-1] | join(', '), 'and', low[-1]] | join(' ') if low | count > 1 else ('No plants' if low | count == 0 else low[0])) ~ ' need watering' }}
I’ve been on this for a whole week would you believe! It appears to have taken only a few minutes to give me a solution, thanks mate, much appreciated!
I actually ended up putting this in but the two statements worked in one conversation response!
{% set low = states.plant | selectattr('attributes.moisture_status','eq','ok') | reject('none')| map(attribute='name') | list %}
{{ ('No plants need' if low | length == 0 else low | join(', and ')+' needs') ~ ' watering and ' }}
{% set low = states.plant | selectattr('attributes.conductivity_status','eq','') | map(attribute='name') | list %}
{{ ('No plants need' if low | length == 0 else low | join(', and ')+' needs') ~ ' feeding' }}
Oddly, it didn’t return anything the first time, but it worked the second time I asked, although I can see in the automation trace that the response was generated. I think the Voice Preview functionality must still be a bit buggy.
Actually, the trigger is the question being asked “how are my plants” , so then yes, this is just a test required.
{# Set a variable that holds the state objects of all the plants with a "Low" moisture reading #}
{%- set plants = states.plant
| selectattr('attributes.moisture_status', 'defined')
| selectattr('attributes.moisture_status', 'eq', 'Low') | list %}
{# Set a variable that holds the entity names from that group that also have a "Low" conductivity reading #}
{%- set feeding = plants
| selectattr('attributes.conductivity_status', 'defined')
| selectattr('attributes.conductivity_status', 'eq', 'Low')
| map(attribute='name') | list %}
{# Set a variable that holds the difference between those two lists (i.e. just the Low moisture entity names) #}
{%- set watering = difference(plants| map(attribute='name') | list, feeding) %}
{%- if feeding -%}
{{-' and '.join((feeding | join(', ')).rsplit(', ', 1)) }} needs feeding
{%- else -%}
no plants need feeding
{%- endif -%}
{{- ' and ' -}}
{%- if watering -%}
{{-' and '.join((watering | join(', ')).rsplit(', ', 1)) }} needs watering
{%- else -%}
no plants need watering
{%- endif -%}
that one is going to take me a while to get my head round !..
Do any of you nice chaps know if it’s possible to populate the entity_id of an automation (obviously in yaml mode) with a template like this? So that all of the returned entity_id’s fill the test section that can then be tested with normal automation visual mode editing?
I had a map function in the wrong place… so the difference function was comparing a list of objects to a list of strings. I have edited my previous post.
For anyone who views this post later with a similar question. The reason I asked about populating an entity with a template is because I didn’t realise you could trigger an automation based on whether a template evaluates to ‘True’ changing from ‘False’.
This could easily fix my other problem automation so that I wouldn’t need to enter each Plant entity_id individually to trigger it, but could ‘OR’ each plant attribute, now, just have to find how to do that…
This forum is a great resource btw.
hmmm… can’t seem to have two solutions to a post, even if there actually are two