🔔 Notification with Confirm, Dismiss and Timeout

:link: Github Link

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.


Hello, this is yet another blueprint script for notifications.

:bulb: Inspiration:

  • Need simple way to create confirmable notifications.
  • There’s confirmable notifications, but did not have timeout actions.
  • Focus was to add timeout feature - wait for X duration for response.
  • Upon timeout, run other actions or dismiss notification.
  • Make it easier to create multistep notification automations.

:warning: Notes:

  • Use at your own risk, no guarantees provided; it’s my first publicly shared blueprint. :grimacing:
  • Tag required for some features, any unique string will do the trick.
    See notifications docs for details.

Version: 1.4

:link: Github Link
:male_detective:t2: Compare Changes

Forked from Home Assistant’s Confirmable Notifications


Features:

  • :calling: Sends a notification to a device with companion app installed.
  • :one: First Action button with custom label and action
  • :two: Second Action button with custom label and action
  • :hourglass: Timeout options with custom duration if no action response received.
  • :broom: Automatically dismiss notification if no response received after timeout.

Example usage:

When the last user leaves home, send a notification to last user:

Example
  • Title: My Awesome Home
  • Message: Turning off lights and appliances in 5 minutes
  • First Action Text: Leave it on
  • First Action Action: Do nothing
  • Second Action Text: Turn off now
  • Second Action Action: Run turn off script
  • Timeout Duration: 5 minutes
  • Timeout Action: Run turn off script
  • Clear on Timeout: Clear Notification

Other examples:


Changelog

Version 1.4 - 7 Jul 2023

:link: Github Link
:male_detective:t2: Compare Changes

  • Reverted: Send clear notification command - for iOS compatibility.
  • Added: subtitle, group, visibility.
  • Refactor: tag is no longer recommended, will use entity_id by default.
  • Fixed: During a timeout, the script throws error into logs due to checking attribs of None type.

Version 1.3.2 - 28 Jun 2023

:link: Github Link
:male_detective:t2: Compare Changes

Changelog

Known Issues:

  • iOS Notifications do not respect Clear after Timeout, issue since version 1.3, slated for fix in version 1.4 (Mid July)
  • Scripts created from blueprint always defaults to mode: single, bug raised with Home Assistant and fixed, hopefully this will be resolved in future releases.
    Update your instances manually if you’re facing any issues with sending multiple notifications within your timeout duration.

Version 1.3.1 - 10 Jun 2023

:link: Github Link
:male_detective:t2: Compare Changes

Changelog
  • Fixed: Enable Icon Color
  • Updated: Icon Color hex template

Version 1.3 - 9 Jun 2023

:link: Github Link
:male_detective:t2: Compare Changes

Changelog

Again, thanks to joe.cole1 for the insights in this minor release.

Also, thanks to RemyyB for identifying the incorrect variable and raising a PR, sorry for taking a week to fix this.

(:crossed_fingers:t2: Color picker is easy enough to configure, so it shouldn’t be absolutely breaking to warrant a major)

Version 1.2 - 30 May 2023

:link: Github Link
:male_detective:t2: Compare Changes

Changelog

Version 1.1 - 25 March 2023

:link: Github Link
:male_detective:t2: Compare Changes

Changelog
  • Updated: Clear on Timeout as boolean field
  • Fixed: Persistent notifications not working
  • Fixed: Clear on Timeout did not clear if a timeout happened

Version 1.0 - 24 March 2023

:link: Github Link

Changelog
  • Initial Release
10 Likes

Thanks for sharing

1 Like

Thanks for sharing I will give it a try!

This is very nice and very clean!

Only feature I would like to see is the ability to notify a group of mobile devices instead of one individual. It’s not a big deal to set up 2 scripts for myself and my wife, but it would be slightly easier to be able to use a notify group.

Thanks! I love the timeout feature.

Edit: I modified and created my own version based off of this. I added the ability to choose a notify service in order to send the same notification to my notifcation groups. I also added a notification icon and icon color (Android only)

blueprint:
  name: My Notifications
  description: Forked from v1.1 of https://github.com/samuelthng/t-house-blueprints/blob/main/notifications.yaml
  domain: script
  input:
    notify_device:
      name: "Notify service (use 'notify.*'. Create a group for multiple)"
      description: Device needs to run the official Home Assistant app to receive
        notifications.
      selector:
        text:
            type: search
    title:
      name: "Title"
      description: The notification title.
      default: ''
      selector:
        text: {}
    message:
      name: "Message"
      description: The notification message body
      selector:
        text: {}
    icon:
      name: "Icon (Android Only)"
      selector:
        icon: {}
    icon_color:
      name: "Icon Color (Android Only, hex or color name)"
      selector:
        text: {}
    confirm_text:
      name: Confirmation Text
      description: Text to show on the confirmation button
      default: Confirm
      selector:
        text: {}
    confirm_action:
      name: Confirmation Action
      description: Action to run when notification is confirmed
      default: []
      selector:
        action: {}
    dismiss_text:
      name: Dismiss Text
      description: Text to show on the dismiss button
      default: Dismiss
      selector:
        text: {}
    dismiss_action:
      name: Dismiss Action
      description: Action to run when notification is dismissed
      default: []
      selector:
        action: {}
    timeout:
      name: Timeout Duration
      description: Amount of time to wait for a confirm/dismiss response before firing
        timeout action.
      selector:
        duration:
          enable_day: false
    timeout_action:
      name: Timeout Action
      description: Action to run when notification response is timed out.
      default: []
      selector:
        action: {}
    tag:
      name: Tag
      description: Used for unique identification of the notification. Must not use underscores.
      selector:
        text: {}
    clear_on_timeout:
      name: "Clear notification on timeout - ⚠️ Tag Required"
      description: Dismiss the notification after action selection times out.
      default: leave_notification
      selector:
        boolean: {}
    persist:
      name: "(Android Only) Persistent Notification - ⚠️ Tag Required"
      description: Ensures that notification cannot be dismissed by swiping away.
      default: false
      selector:
        boolean: {}
    channel:
      name: (Android Only) Notification Channel
      description: Defines the channel, to be used with Importance. Relates to the
        importance of the notification.
      default: General
      selector:
        select:
          options:
          - label: General
            value: General
          - label: Alarm
            value: Alarm
          - label: Brewery
            value: Brewery
          - label: Door
            value: Door
          multiple: false
          custom_value: true
    importance:
      name: (Android Only) Notification Channel Importance
      description: https://companion.home-assistant.io/docs/notifications/notifications-basic/#notification-channel-importance
      default: default
      selector:
        select:
          options:
          - label: Urgent (Makes a sound with heads-up notification)
            value: high
          - label: Default (Makes a sound)
            value: default
          - label: Silent (Makes no sound)
            value: low
          - label: Low (Makes no sound, doesn't appear in status bar)
            value: min
          multiple: false
          custom_value: false
    interruption_level:
      name: (IOS Only) Interruption Level
      description: https://companion.home-assistant.io/docs/notifications/notifications-basic/#interruption-level
      default: active
      selector:
        select:
          options:
          - label: Silent (Makes no sound, does not wake screen)
            value: passive
          - label: Default
            value: active
          - label: Important (Overrides Focus)
            value: time-sensitive
          - label: Critical (Overrides Focus and Mute, restricted features)
            value: critical
          multiple: false
          custom_value: false
mode: restart
sequence:
- alias: Set up variables
  variables:
    action_confirm: '{{ ''CONFIRM_'' ~ context.id }}'
    action_dismiss: '{{ ''DISMISS_'' ~ context.id }}'
    clear_on_timeout: !input clear_on_timeout
    persist: !input persist
- alias: Send notification
  service: !input notify_device
  data:
    title: !input title
    message: !input message
    data:
      actions:
      - action: '{{ action_confirm }}'
        title: !input confirm_text
      - action: '{{ action_dismiss }}'
        title: !input dismiss_text
      tag: !input tag
      notification_icon: !input icon
      color: !input icon_color
      persistent: !input persist
      timeout: !input timeout
      channel: !input channel
      importance: !input importance
      push:
        interruption-level: !input interruption_level
- alias: Awaiting response
  wait_for_trigger:
  - platform: event
    event_type: mobile_app_notification_action
    event_data:
      action: '{{ action_confirm }}'
  - platform: event
    event_type: mobile_app_notification_action
    event_data:
      action: '{{ action_dismiss }}'
  timeout: !input timeout
  continue_on_timeout: true
- choose:
  - conditions: '{{ wait.trigger.event.data.action == action_confirm }}'
    sequence: !input confirm_action
  - conditions: '{{ wait.trigger.event.data.action == action_dismiss }}'
    sequence: !input dismiss_action
  - conditions: '{{ wait.trigger == none }}'
    sequence: !input timeout_action
- if:
  - alias: Clear Notification Enabled
    condition: template
    value_template: '{{ clear_on_timeout == true }}'
  then:
  - alias: Send notification
    service: !input notify_device
    data:
      message: "clear_notification"
      data:
        tag: !input tag
2 Likes

Where should I set the condition ?
I want to send a notification if my garage door is open for more than 2h or if it’s any time after 10pm.
Thank you.

@ablyes this is just a script that you need to call from something else. So in your case, create an automation with triggers for garage door state open for 2 hours and another trigger for after 10pm with condition garage door open. Then in the action, you would simply call this script that you created and saved.

Super easy!

Makes sens. It’s working fine now :slightly_smiling_face:
Why is the iOS notification so tricky ? I have to click on it for 3 sec to see the actions.

Can we enhance the human interaction ? Like a click on the notification that show the big button to do the action if we miss the 3 sec ?

@ablyes Sadly it’s the default behaviour of the companion app :frowning:
My wife has the same complaint… :sob:

Maybe it would be wise for the notification to open HA instead when it is clicked.

Thank you for sharing your changes! Have added a link to your comment under the forks subheader, and will review the changes to be added in future versions!

P.S. may take awhile, got a bad case of COVID :frowning:, will do testing and changes after I’m back.

Sounds good! I’m certainly no power user, so I’m sure it could be done better.

Another frustration I have that I don’t see a way to fix is the timeout function.

If you don’t clear the notification on timeout, the action buttons no longer work. But a timeout is required, so you either have to set a very long timeout (for example 24 hours) and don’t clear the notification, or you have to use a timeout action.

I think the answer for me is going to be create a blueprint without the timeout functionality for when I don’t need it, but I was curious of your thoughts.

Edit: For now I’ve created another blueprint without any timeout functions. I’m sure there’s a way to set a variable to either use or not use the timeout function if it’s set, but I don’t have the know-how to do that!

That’s a good point that I did not face in my use case.

I’ll have to do some digging into the docs to see if we can use some data payloads when triggering the script.

It’s a great suggestion and valid use case, I’ll add that to the list of things to think about! :+1:t2:

Maybe just to help me understand better, could you go into a little more detail for your use case? The ideal flow you’re expecting the script to be capable of, and the context would be helpful!

Sure thing!

I have this triggered from my garage door opening. I have it set to persistent, with the actions being Close Door and Dismiss.

I don’t want the notification to timeout, and there’s no action I want to perform after a timeout.

So I left timeout action blank and timeout time set to the default, 0.

The problem is the actions didn’t work, as it would see that as timing out immediately and the “triggered by” would run with the timeout action (none)

So my other action buttons didn’t work, as the timeout action already “ran” and the script was no longer listening for the other actions.

:partying_face: Update: Version 1.2

  • Added: Icon and Icon Color options for Android, big thanks to @joe.cole1 for adding it!
  • Added: Option to enable or disable the timeout.
    • For cases where command buttons should work indefinitely.
    • :warning: When enabled, will not trigger Timeout Actions.

I’m glad to say the changes this time are all backwards compatible.

How to update:

  1. Replace blueprint file at config/blueprints/script/samuelthng/notifications.yaml with intended version.

  2. Reload your scripts on the Developer Tools Yaml page, or use this button:
    Open your Home Assistant instance and show your service developer tools with a specific service selected.

  3. Check your scripts!
    It should show the new options and trigger properly if the upgrade went well.

2 Likes

This is an amazing blueprint, thanks a lot for sharing!

How is Timeout supposed to work on iOS? I’m setting tag, timeout action and timeout duration but the action is never triggered

Looks like clear_on_timeout is not properly initialized so turning it off and back on fixed the issue.

Changing line 131 from

default: "leave_notification"

to

default: true

Fixes the variable and creating a new notification executes the timeout action correctly

EDIT 2: I see you already had a PR for this issue, nice!

2 Likes

Good eye! Yeah I missed that in the initial commit, should be fixed after V1.1

1 Like

@samuelthng I have a few other ideas I’d like to see about implementing. Namely a clickAction so that if you tap on the notification it opens a URL/navigates to a specific spot in the app.

It’s a simple call under data, in the same spot as the icon and color. Unfortunately, it’s named clickAction for Android, and just url for iPhone… so there’s probably not a good way to implement this universally and easily.

clickAction: "lovelace/home" #Android
url: "lovelace/home" #iPhone

Another idea I had is in regards to timeouts.

I had a weird case today where the timeout occurred when my phone was without reception. It did not receive the clear_notification notification from the automation timing out, so the notification remained even though the script had already timed out.

It might be a bit cleaner to include the following in the notification itself if timeout is enabled. That way the app on the phone removes the notification instead of relying on home assistant to send a clear_notification to the device. This is also under data: in the notification setup and would only be set if clear_on_timeout and timeout_duration are both set.

timeout: 600 # How many seconds the notification should be received by the device

I’ve had a few different blueprints for notifications and this has quickly become my favorite by far!

2 Likes

Great suggestions yet again! Yeah we could probably work those in.

We might still need the current timeout just for the sake of triggering timeout action HA side, but using the same timeout variable.

I’ll give it some brain cell time :joy:

2 Likes

Exactly. I didn’t come up with a clean solution myself… I’m more of an ideas guy!

Eventually it could get so complicated you might as well just copy and paste all the code anyway! :stuck_out_tongue:

:partying_face: Update: Version 1.3

Again, thanks to joe.cole1 for the insights in this minor release.
Also, thanks to RemyyB for identifying the incorrect variable and raising a PR.
Sorry to everyone for taking a week to fix this. 🙇🏻‍♂️

(:crossed_fingers:t2: Color picker is easy enough to configure, so it shouldn’t be absolutely breaking to warrant a major)

How to update

Things to check after updating:

  • Clear Notification is correctly set/unset
  • Icon Color and Enable Icon Color are correctly set/unset
  • All scripts using this blueprint are loaded in the scripts list
    • If they are missing, don’t worry, do drop a message here with me tagged and we’ll get it fixed.
1 Like

Usage Example: Notification script for Home Assistant Core Updates

This script would notify the user that a new update is available, with an option to call the update service, or the skip update service.

Upon clicking the notification - not the action buttons - it will navigate the user to the Home Assistant updates page.

If nothing has been selected for 30 minutes, the notification will be cleared automatically without taking any actions.

Code
notify_home_assistant_core_update:
  alias: "\U0001F514 Home Assistant Core Update Notification"
  use_blueprint:
    path: samuelthng/notifications.yaml
    input:
      notify_device: <my_device_entity_id>
      title: My Awesome Home
      message: New update available!
      timeout:
        hours: 0
        minutes: 30
        seconds: 0
      tag: ha_core_update
      clear_on_timeout: true
      notification_link: /config/updates
      icon: mdi:archive-arrow-up
      enable_icon_color: true
      icon_color:
      - 98
      - 234
      - 125
      confirm_text: Update Now
      confirm_action:
      - service: update.install
        data:
          backup: true
        target:
          entity_id: update.home_assistant_core_update
      dismiss_text: Skip
      dismiss_action:
      - service: update.skip
        data: {}
        target:
          entity_id: update.home_assistant_core_update