A typical automation would look something like following:
mode: single
trigger:
- platform: sun
event: sunrise
offset: 0
condition: []
action:
- service: notify.smtp
data:
message: Good morning!
target:
- !secret email_a
- !secret email_b
- !secret email_c
Now I want to create a dashboard in the UI where all the users (a, b & c) will have option to check or uncheck their names for receiving notification. Please help me figure out how to parse a dynamic list of targets for the SMTP service.
Just be aware that trigger variables only allow Limited templates, so they don’t have access to the state machine and some other common templating options.
I just tested the code and it works like a charm, thanks for sharing this solution!
Another question, I’ve around 20 automation that provides various notifications to our family. Do I need to add this code in each automation individually or is there a smarter way to reuse this code across multiple automations?
To make it easier to use in multiple automations you’d be better off the set it up as a script instead. One caveat, since scripts don’t have an analog to trigger_variables, to use secrets you’ll need to set the script up in YAML, not in the UI script editor and not in scripts.yaml.
alias: Email opted-in Users
mode: single
fields:
message:
name: Message
description: The message to send
example: "Good Morning"
required: true
variables:
a: !secret email_a
b: !secret email_b
c: !secret email_c
mapper:
input_boolean.a: "{{ a }}"
input_boolean.b: "{{ b }}"
input_boolean.c: "{{ c }}"
targets: |
{% set ns = namespace( emails=[] ) %}
{% set bools = ['input_boolean.a', 'input_boolean.b', 'input_boolean.c'] | select('is_state', 'on') | list %}
{% for my_bool in bools %}
{% set ns.emails = ns.emails + [ mapper.get(my_bool) ]%}
{% endfor %}{{ ns.emails }}
sequence:
- service: notify.smtp
data:
message: "{{ message }}"
target: "{{ targets }}"
Then your automation would then be:
mode: single
trigger:
- platform: sun
event: sunrise
offset: 0
condition: []
action:
- service: script.email_opted_in_users
data:
message: Good morning!
Thanks for suggestions, I am running into some problem while testing the above script.
I copied the code into scripts.yaml in the configuration folder and saved the file and reloaded the scripts. In the scripts view, I am not seeing a script named “Email opted_in users” but two different new items named “fields” and “variables” (see screenshot below).
These blocks would not open in normal script UI editor as you rightly mentioned in your note above, in Visual Studio Code the scripts.yaml shows the full pasted code without truncation and there are no errors to provide any insights into what might be happening here.
I’ve no experience of using code block you recommended, please see if you spot any possible error what is not allowing this script to be loaded like a normal service.
Thanks.
Yes putting it in configuration.yaml worked and now I’m little confused as I’ve been using code refactorization and have following additional lines in the configuration.yaml:
The folder “./refactored/scripts” has few other scripts that are identified correctly. And my undestanding is that refactoring code in above manner is only for housekeeping as HA generates the same YAML syntax (expanded one) after collapsing all files and folders under “/refactored/scripts”.
Is there a reason why this code works in configuration.yaml but not in scripts.yaml?
PS: But thanks for helping solve this complex situation!!
If it works in configuration.yaml it should work as a file in you refactored folder. I am no expert when it comes to all the various ways the config can be split… as soon as I found out about Packages I stopped bothering with the other options.
This may not be completely accurate, but my understanding is that scripts.yaml and automations.yaml are subject to some sort of extra processing to make them work with the UI editors. That processing doesn’t play nice with YAML methods like nodes, anchors, and tags, so you should not use them in those two files. One exception to this is that the !secret tag can be used in trigger_variables, there may be others that I am unaware of.
Thanks and the explanation does make intuitive sense as the UI editor is optimized for user friendliness. From my early days, I do recall the frustration of typing YAML code blocks and all the mistakes I used to make around closing quotes and indentations!
Thanks again for walking me through this solution!
@Didgeridrew Drew, if I may ask for some more help to make this one little smarter.
Here are the things that I am doing or planning on doing:
Created a UI where each user can select or deselect notifications specific to each event.
So there are three distinct set of lists in this context:
a. Users
b. Events or automatons that can broadcast notifications (for example, dishwasher cycle finished)
c. Input boolean for each user (for each event) that can be toggled, so if there are 2 users and 3 events then there will be a grid of 2x3=6 input boolean as shown in the screenshot above.
Trying to write a script that will have hard coded information on 2(a)(b) and 2(c) and there is a field in the script (“dynamic_opt_in-event”) which will pass the specific event type from an automation.
The idea is that if there is an automation of notification related to dishwasher, the automation can pass “dynamic_opt_in-event=dishwasher” and the script should be able to parse the list of recipients who have opted to receive notifications related to dishwasher.
I started tweaking the code you shared earlier but clearly I’m not doing it correctly, please see if you can spot any obvious error in my approach:
dynamic_email_opt_in:
alias: Dynamically opt in for notifications
mode: single
fields:
dyanmic_opt_in-event:
required: true
variables:
users:
- !secret pankaj_cell
- !secret pankaj_email
notification events:
dishwasher:
- input_boolean.pankaj_email_dishwasher
- input_boolean.pankaj_sms_dishwasher
laundry_washer:
- input_boolean.pankaj_email_laundry_washer
- input_boolean.pankaj_sms_laundry_washer
laundry_dryer:
- input_boolean.pankaj_email_laundry_dryer
- input_boolean.pankaj_sms_laundry_dryer
dynamic_list: |
{% set ns = namespace( dynamics=[] ) %}
{% for notifcation_event in notification_events['dishwasher'] %}
{% if states('notifcation_event') ='on'}
{% set ns.dynamics = ns.dynamics + [ (my_bool) ]%}
{% endfor %}{{ ns.dynamics }}
sequence:
- service: notify.smtp_gmail
data:
title: Dynamic opt-in list
message: Some msg here
target: "{{ dynamic_list }}"
If you can think of a more efficient way to manage this dynamic opt-in list, please send me few pointers.
Thanks.