Skip to content

Commit

Permalink
Refactor: Evaluate OS specific payload separately.
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelthng committed Nov 1, 2023
1 parent 88c1734 commit d44964b
Showing 1 changed file with 75 additions and 34 deletions.
109 changes: 75 additions & 34 deletions notifications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ blueprint:
description: >-
<div>
<h2>🔔 Notifications</h2>
<h4> Version 1.6.1 - Multi-device<a href="https://github.com/samuelthng/t-house-blueprints/blob/main/notifications.yaml" target="_blank">🔗 Github Link</a><br /></h4>
<h4> Version 2 Beta 1 - Multi-device | <a href="https://github.com/samuelthng/t-house-blueprints/blob/main/notifications.yaml" target="_blank">🔗 Github Link</a><br /></h4>
<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fmy.home-assistant.io%2Fredirect%2Fblueprint_import%2F%3Fblueprint_url%3Dhttps%253A%252F%252Fgithub.com%252Fsamuelthng%252Ft-house-blueprints%252Fblob%252Fmain%252Fnotifications.yaml" target="_blank">
<img src="https://my.home-assistant.io/badges/blueprint_import.svg" alt="Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled." />
</a>
Expand Down Expand Up @@ -39,6 +39,10 @@ blueprint:
<details>
<summary>Expand/collapse changelog</summary>
### Version 2 Beta 1 Multiple Device - *1 Nov 2023*
- Refactor: Build payload in templates
- Fixed: iOS showing `Failed to load attachment`
### Version 1.6.1 Multiple Device - *31 Oct 2023*
- Added: Experimental Multiple Device Support
Expand Down Expand Up @@ -656,6 +660,12 @@ blueprint:
default: false
selector:
boolean:
car_ui:
name: "🚘 Show on Android Auto"
description: "Display notification on Android Auto interface. \n\n`🤖 Android Only`"
default: false
selector:
boolean:

##############################
# Input: Notification Link
Expand Down Expand Up @@ -774,6 +784,11 @@ sequence:
##############################
- alias: "Setup variables"
variables:
subtitle: !input subtitle
interruption_level: !input interruption_level
notification_link: !input notification_link
visibility: !input visibility
importance: !input importance
custom_tag: !input tag # No need for manual definition anymore, treat existing definitions as custom tags.
first_option: "{{ 'FIRST_' ~ context.id }}"
second_option: "{{ 'SECOND_' ~ context.id }}"
Expand All @@ -783,6 +798,8 @@ sequence:
persist: !input persist
timeout: !input timeout # Load timeout into variable for use with templates.
timeout_seconds: "{{ (timeout.hours * 60 + timeout.minutes) * 60 + timeout.seconds }}"
car_ui: !input car_ui
icon: !input icon
enable_icon_color: !input enable_icon_color
icon_color_selector: !input icon_color
icon_color_hex: '{{ "#{:02x}{:02x}{:02x}".format(icon_color_selector[0], icon_color_selector[1], icon_color_selector[2]) }}'
Expand Down Expand Up @@ -917,6 +934,49 @@ sequence:
options: >-
{{ [option_one, option_two, option_three] | selectattr('enabled') | list }}
tag: "{{ iif(custom_tag|length, tag, this.entity_id ~ '-' ~ context.id) }}"
# Build OS specific notification payloads.
notification_data: >-
{% set notifications = namespace(data=[])%}
{% set memo = namespace(data={})%}
{% for device in notify_device %}
{% set apple_device = 'APPLE' in (device_attr(device, "manufacturer")|upper) %}
{% set memo_key = 'APPLE' if apple_device else 'ANDROID' %}
{% if not memo_key in memo.data %}
{# If OS payload not built yet, evaluate it. #}
{% set p = namespace(d={ 'apple_device': apple_device }) %}
{% if p.d.apple_device %}
{# iOS #}
{% set push = namespace(d={}) %}
{% set p.d = dict(p.d, **{ 'subtitle': subtitle }) %}
{% set push.d = dict(push.d, **{ 'interruption-level': interruption_level }) %}
{% if notification_link|length %}{% set p.d = dict(p.d, **{ 'url': notification_link }) %}{% endif %}
{% if attachment_type == 'camera_entity' %}{% set p.d = dict(p.d, **{ 'entity_id': attachment_camera_entity }) %}{% endif %}
{% set p.d = dict(p.d, **{ 'push': push.d }) %}
{% else %}
{# Android #}
{% set p.d = dict(p.d, **{ 'subject': subtitle }) %}
{% set p.d = dict(p.d, **{ 'visibility': visibility }) %}
{% set p.d = dict(p.d, **{ 'importance': importance }) %}
{% if notification_link|length %}{% set p.d = dict(p.d, **{ 'clickAction': notification_link }) %}{% endif %}
{% if attachment_type == 'camera_entity' and (media_url|length) %}{% set p.d = dict(p.d, **{ 'image': media_url }) %}{% endif %}
{% if icon|length %}{% set p.d = dict(p.d, **{ 'notification_icon': icon }) %}{% endif %}
{% if enable_icon_color %}{% set p.d = dict(p.d, **{ 'color': icon_color_hex }) %}{% endif %}
{% if enable_timeout and clear_on_timeout %}{% set p.d = dict(p.d, **{ 'timeout': timeout_seconds }) %}{% endif %}
{% if channel|length %}{% set p.d = dict(p.d, **{ 'channel': channel }) %}{% endif %}
{% if persist %}{% set p.d = dict(p.d, **{ 'persistent': persist }) %}{% endif %}
{% if car_ui %}{% set p.d = dict(p.d, **{ 'car_ui': car_ui }) %}{% endif %}
{% endif %}
{# Common #}
{% set p.d = dict(p.d, **{ 'actions': options }) %}
{% set p.d = dict(p.d, **{ 'tag': tag }) %}
{% if group|length %}{% set p.d = dict(p.d, **{ 'group': group }) %}{% endif %}
{# Push payload to array #}
{% set memo.data = dict(memo.data, **{ "{}".format(memo_key): p.d }) %}
{% endif %}
{# Update notification data array with the memoized payload. #}
{% set notifications.data = notifications.data + [memo.data[memo_key]] %}
{% endfor %}
{{ notifications.data }}
##############################
# Send Notification
Expand All @@ -929,28 +989,8 @@ sequence:
data:
title: !input title
message: !input message
data:
subtitle: !input subtitle # iOS/macOS
subject: !input subtitle # Android
actions: "{{ options }}"
visbility: !input visibility
tag: "{{ tag }}"
group: "{{ iif(group|length, group, ) }}"
persistent: !input persist
channel: !input channel
importance: !input importance
push:
interruption-level: !input interruption_level
notification_icon: !input icon
color: "{{ iif(enable_icon_color, icon_color_hex, )}}"
clickAction: !input notification_link
url: !input notification_link
timeout: "{{ iif(enable_timeout and clear_on_timeout, timeout_seconds, )}}" # Set notification timeout if timeout feature is enabled and notification should be cleared.
# [Attachments]
entity_id: "{{ iif(attachment_type == 'camera_entity' and 'camera.' in attachment_camera_entity, attachment_camera_entity,) }}" # - Camera Stream (iOS)
image: "{{ media_url }}"
video: "{{ media_url }}"
audio: "{{ media_url }}"
data: >-
{{ notification_data[repeat.index - 1] }}
##############################
# Evaluate Response
Expand Down Expand Up @@ -978,7 +1018,7 @@ sequence:
event_type: mobile_app_notification_cleared
event_data:
tag: "{{ tag }}"
timeout: !input timeout
timeout: "{{ timeout }}"
continue_on_timeout: true
else:
- alias: "Awaiting response indefinitely…"
Expand Down Expand Up @@ -1023,16 +1063,17 @@ sequence:
##############################
# Compatibility: iOS Clear Notification
##############################
- if:
- alias: "Should send clear notification command? (for iOS/macOS)"
condition: template
value_template: "{{ enable_timeout and clear_on_timeout }}"
then:
- alias: "Send clear notification command"
repeat:
for_each: "{{ notify_service }}"
sequence:
- service: "{{ repeat.item }}"
- alias: "Send clear notification commands"
repeat:
for_each: "{{ notify_service }}"
sequence:
- if:
- alias: "Should send clear notification command? (for iOS/macOS)?"
condition: template
value_template: "{{ enable_timeout and clear_on_timeout and notification_data[repeat.index - 1].apple_device }}"
then:
- alias: "Send clear notification command to iOS device"
service: "{{ repeat.item }}"
data:
message: "clear_notification"
data:
Expand Down

0 comments on commit d44964b

Please sign in to comment.