Conditional notification (notify)

As far as I could find there is no way to have a notification service that forwards notifications conditionally.

For example, I have automations where notifications are sent but I do not want these notifications to arrive when I or my wife are in the office.

Obviously, writing conditions in those automations is possible but that becomes cluttered rather quick. I would prefer to have a notification group that takes those conditions in consideration.

So… I made it.

in configuration.yaml:

notify:
  - name: conditional
    platform: group
    services:
      - services: empty

This creates the service notify.conditional that leads nowhere. (let’s say a dummy)

the accompanying automation:

alias: 'notify.conditional_high '
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: notify
      service: conditional
# This trigger intercepts the call service notify.conditional
action:
  - choose:
      - conditions:
          - condition: and
            conditions:
              - condition: state
                entity_id: input_boolean.wife_notify
                state: 'on'
              - condition: state
                entity_id: input_boolean.me_notify
                state: 'on'
        sequence:
          - service: notify.wife_and_me
            data:
              message: '{{ trigger.event.data.service_data.message }}'
              title: '{{ trigger.event.data.service_data.title }}'
      - conditions:
          - condition: and
            conditions:
              - condition: state
                entity_id: input_boolean.me_notify
                state: 'on'
              - condition: state
                entity_id: input_boolean.wife_notify
                state: 'off'
        sequence:
          - service: notify.me
            data:
              message: '{{ trigger.event.data.service_data.message }}'
              title: '{{ trigger.event.data.service_data.title }}'
      - conditions:
          - condition: and
            conditions:
              - condition: state
                entity_id: input_boolean.me_notify
                state: 'off'
              - condition: state
                entity_id: input_boolean.wife_notify
                state: 'on'
        sequence:
          - service: notify.wife
            data:
              message: '{{ trigger.event.data.service_data.message }}'
              title: '{{ trigger.event.data.service_data.title }}'
    default:
      - service: notify.persistent_notification
        data:
          message: '{{ trigger.event.data.service_data.message }}'
          title: '{{ trigger.event.data.service_data.title }}'
mode: single

The action part of this automation looks at which input booleans are turned on (the conditional part) and based on that forwards the title and message from the original service call to the notify services that are set to available.

This could be much simpler but this works.

The input booleans can of course be turned off and on in an automation based on zone, time or whatever you fancy.

2 Likes

I was actually planning on making a post about using this notifier group hack for use with the Alert integration. It’s the only way I’ve found to harness the variable repeat interval and “done message” functions of the alerts while still being able to apply conditional logic so that they are routed to an appropriate output or to insert other actions such as applying volume control to alerts being sent to TTS devices.

FWIW, you can also use an empty set as the value for services:

notify:
  - platform: group
    name: tts_alerts
    services: []
Alert Example
##configuration.yaml
alert:
  cpu_temp:
    name: Alert Hot CPU
    message: "The CPU has reached {{ states('sensor.cpu') }} degrees"
    done_message: CPU is now below 70 degrees
    entity_id: binary_sensor.cpu_above_70
    state: "on"
    repeat: 10
    can_acknowledge: true
    skip_first: false
    notifiers:
      - tts_alerts 
      - mobile_app_d

Automation:

alias: Only Alerts
description: 'Turn volume up, Play message from "tts_alerts", turn volume down'
trigger:
  platform: event
  event_type: call_service
  event_data:
    domain: notify
    service: tts_alerts
condition: []
action:
  - service: media_player.volume_set
    data:
      volume_level: 0.5
    target:
      entity_id:
        - media_player.1
        - media_player.2
  - delay: 2
  - service: notify.your_tts_service_or_tts_notifier_group
    data:
      message: '{{trigger.event.data.service_data.message}}'
  - alias: "Wait for tts to finish"
    wait_for_trigger:
    - platform: state
      entity_id: media_player.1
      from: "playing"
      to: "idle"
  - service: media_player.volume_set
    data:
      volume_level: 0.3
    target:
      entity_id:
        - media_player.1
        - media_player.2

Credit where it is due, I first found out about this hack from this post from 2019 by @pnbruckner

1 Like

Good point about the empty set as a value for services.

I’ll adjust the post accordingly.

using the alert integration with this is interesting! I’ll have to take a look at that.

I definitely have some work to do this weekend playing with what you suggest here with the alerts.

regarding the " services: []" that broke it so I changed it back to “empty”. Theoretically, it should work as you suggested but somehow it won’t accept it.

Strange… what I posted is straight from my config and is definitely working.

Strange indeed because I copy-pasted what you wrote here into my config…

oh well “empty” or whatever works just as well

1 Like

I also needed to pass data while allowing it to be empty (and might as well pass target while we’re at it):

data:
  message: "{{ trigger.event.data.service_data.message }}"
  title: "{{ trigger.event.data.service_data.title }}"
  target: "{{ trigger.event.data.service_data.target }}"
  data: "{{ trigger.event.data.service_data.data | default('{}') }}"
1 Like