Apologies if I’m repeating previous Q and A’s:
Is there a way to implement this as a script instead of an automation?
It would be useful to be able to pass variables on-the-fly, instead of creating multiple automations, each with a different set of variables. Then you just call script.actionable_notifications, and pass your desired arguments for that situation.
For that purpose, scripts offer fields to set variables for the sequence section (equivalent to inputs in automations).
I’ve tried porting this automation, see below:
alias: Actionable notifications for Android
description: |
Send actionable notifications to an Android device
Inspired by https://community.home-assistant.io/t/actionable-notifications-for-android/256773
fields:
notify_device:
name: Device to notify
description: Device needs to run the official Home Assistant app to receive notifications
required: true
selector:
device:
integration: mobile_app
notification_title:
name: Notification title
description: The title of the notification
default: ""
selector:
text:
notification_message:
name: Notification message
description: The message of the notification
default: ""
selector:
text:
persistent_notification:
name: Create persistent notification?
description: Persistent notifications cannot be dimissed by swiping away
required: true
default: false
selector:
boolean:
# Action 1
action_1_title:
name: "Button 1: name"
description: Name of the first button
required: true
default: ""
selector:
text:
action_1_uri:
name: "Button 1: URI (Optional)"
description: Optional URI for the first button
default: ""
selector:
text:
action_1_action:
name: "Button 1: action"
description: Action(s) to run when the first button is clicked
required: true
default: []
selector:
action:
# Action 2
action_2_title:
name: "Button 2: name"
description: Name of the second button
required: true
default: ""
selector:
text:
action_2_uri:
name: "Button 2: URI (Optional)"
description: Optional URI for the second button
default: ""
selector:
text:
action_2_action:
name: "Button 2: action"
description: Action(s) to run when the second button is clicked
required: true
default: []
selector:
action:
# Action 3
action_3_title:
name: "Button 3: name"
description: Name of the third button
required: true
default: ""
selector:
text:
action_3_uri:
name: "Button 3: URI (Optional)"
description: Optional URI for the third button
default: ""
selector:
text:
action_3_action:
name: "Button 3: action"
description: Action(s) to run when the third button is clicked
required: true
default: []
selector:
action:
mode: single
sequence:
- alias: Send actionable notification
domain: mobile_app
type: notify
device_id: "{{ notify_device }}"
title: "{{ notification_title }}"
message: "{{ notification_message }}"
data:
tag: "{{ notification_title }}"
persistent: "{{ persistent_notification }}"
actions: >
{% set titles = [action_1_title, action_2_title, action_3_title] %}
{% set uris = [action_1_uri, action_2_uri, action_3_uri] %}
{% set actions = namespace(data = []) %}
{% for title in titles %}
{% if title|length %}
{% set uri = uris[loop.index - 1] %}
{% set action_name = "action" + loop.index|string %}
{% set action = {
"action": "URI" if uri|length else action_name,
"title": title,
"uri": uri
}
%}
{% set actions.data = actions.data + [action] %}
{% endif %}
{% endfor %}
{{ actions.data }}
- alias: Wait for the user to select an action
wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
- platform: event
event_type: mobile_app_notification_cleared
- alias: Do the action that the user selected
choose:
- conditions: "{{ wait.trigger.event.data.action == 'action1' }}"
sequence: "{{ action_1_action }}"
- conditions: "{{ wait.trigger.event.data.action == 'action2' }}"
sequence: "{{ action_2_action }}"
- conditions: "{{ wait.trigger.event.data.action == 'action3' }}"
sequence: "{{ action_3_action }}"
When I reload scripts, I keep getting an error for the last (and most important) step in the sequence: Invalid config for [script]: expected dictionary @ data['sequence'][2]['choose'][0]['sequence'][0]. Got None.
I don’t this is possible with the current setup, but i’m looking for a way for the notification to clear once the boolean has been cleared. For example i have a garage door and i want this mobile notification to appear when it is opened. However if i manually close the garage door (or use my garage door opener), once the door is closed, i am looking for this notification to be automatically cleared as this is no longer needed. I think the workaround would be to use the tag and clear the notification from another automation.
I started by converting into a script instead of automation
This led to a world of hurt I ran into two main problems:
the script needed to handle an unknown number of actions (1-3)
the script needed to handle arbitrary actions without knowing their parameters beforehand
You can find my struggles and the main error I encountered here
The workaround was a combination:
A script to allow the user to define the buttons and arbitrary actions
A python script to accept any number of arbitrary actions and execute the chosen one (see here on how to setup python scripts in HA)
BONUS: I also added context.id to prevent multiple notifications from interfering with one another
Here’s the end product, trimmed down for legibility:
# /config/scripts.yaml
actionable_notification:
# ...
fields:
# ...
action_1_title:
name: 'Button 1: name'
description: Name of the first button
required: true
default: ''
selector:
text:
action_1_uri:
name: 'Button 1: URI (Optional)'
description: Optional URI for the first button
default: ''
selector:
text:
action_1_action:
name: 'Button 1: service call(s)'
description: Service(s) to run when the first button is clicked
required: true
default: []
selector:
action:
# actions 2 and 3 are optional
action_2_title:
name: 'Button 2 (Optional): name'
description: Name of the second button
selector:
text:
action_2_uri:
name: 'Button 2 (Optional): URI (Optional)'
description: Optional URI for the second button
selector:
text:
action_2_action:
name: 'Button 2 (Optional): service call(s)'
description: Service(s) to run when the second button is clicked
required: true
default: []
selector:
action:
# ... action 3 is same as 2
mode: single
sequence:
- variables:
title: '{{ notification_title if notification_title is defined else "" }}'
message: '{{ notification_message if notification_message is defined else ""}}'
action_1:
action: '{{ "action1" ~ context.id }}'
title: '{{ action_1_title }}'
uri: '{{ action_1_uri if action_1_uri is defined else "" }}'
action_2:
action: '{{ "action2" ~ context.id }}'
title: '{{ action_2_title if action_2_title is defined else "" }}'
uri: '{{ action_2_uri if action_2_uri is defined else "" }}'
# action_3...
# Send actionable notification
- service: '{{ notify_service }}'
data:
title: '{{ title }}'
message: '{{ message }}'
data:
tag: '{{ title }}'
persistent: '{{ persistent_notification if persistent_notification is defined
else false }}'
actions: >
{% set actions_raw = [action_1, action_2, action_3] %}
{% set actions = namespace(data = []) %}
{% for action in actions_raw %}
{% if action["title"]|string|length %}
{% set actions.data = actions.data + [action] %}
{% endif %}
{% endfor %}
{{ actions.data }}
# Wait for the user to select an action
- wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
- platform: event
event_type: mobile_app_notification_cleared
# Check that we have a chosen action
- condition: template
value_template: '{{ wait.trigger.event.data.action is defined }}'
# Send the actions and the choice to python script
- service: python_script.actionable_notifications_execute
data:
actions: >
{{ [
action_1_action,
action_2_action if action_2_action is defined else [],
action_3_action if action_3_action is defined else []
] }}
chosen: '{{ wait.trigger.event.data.action }}'
event: '{{ wait.trigger.event }}'
context_id: '{{ context.id }}'
# /config/python_scripts/services.yaml
actionable_notifications_execute:
name: Execute actionable notifications
description: Execute the chosen actions from a list presented in a notification
fields:
actions:
description: The potential actions to execute
chosen:
description: The chosen action ("action[num]")
context_id:
description: The (automatically-generated) notification context ID. Prevents confusion with other notifications' events.
# /config/python_scripts/actionable_notifications_execute.py
def get_param(service):
if "data" in service:
return service["data"]
if "target" in service:
return service["target"]
return null
actions = data.get("actions")
chosen = data.get("chosen")
context_id = data.get("context_id")
index = int(chosen.replace(context_id, '')[-1]) - 1
for service in actions[index]:
service_name = service.pop("service")
domain, name = service_name.split(".")
param = get_param(service)
hass.services.call(domain, name, param)
This is an awesome feature, glad I found this. I only have a couple smart bulbs but love the idea of getting a notification if my lights turn on (while I am not in my home zone), and being able to turn them off through the notification, which shows up correctly on my smart watch!
alert:
garage_door_open:
name: "Garage Door Open"
title: "Garage Door Open"
message: "The garage door is open."
done_message: clear_notification
entity_id: cover.garage_door_opener
state: open
repeat: 60
notifiers: mobile
Is there any way to auto-dismiss this notification once the condition has resolved? (e.g. on the garage door scenario, when someone manually closes the garage door)
i dont understand what im missing here. Im only seeing a notification in the HA companion app and its only showing the name of the message and its just showing the yaml for the button and the action i am trying to use. I cant get any notifictions on my phone period,
Anyway to include an attachment to the notification, for example:
service: notify.mobile_app_<your_device_id_here>
data:
message: "Something happened at home!"
data:
# an example of an absolute url
image: "https://github.com/home-assistant/assets/blob/6a407898bd8ae80eb83634ffddb0d5ebdde95957/logo/logo.png?raw=true"