Create simple, actionable notifications with Home Assistant using Node-RED and the Home Assistant Companion App

What are actionable notifications?

Actionable notifications are notifications that are sent to your device (in this case, Android or Apple IOS) that allow you to perform an action if a condition is met.

For example, maybe you and your family are away from the house for 10 minutes, and you want to be notified if a door is left open? Or perhaps you want to set your alarm system on when you leave your house?

Another example: I have a bedtime routine for my child that will turn off lights, turn on the fan, set the sound machine and humidifier to on, and after 10 minutes it will ask me if I want to turn the night light off or not.

Requirements to setup actionable notifications:

There are a few prerequisites, I assume that you have the following before starting:

We’re also going to assume that you’ve had some experience setting up automations in node-red, you may be able to complete this tutorial without any prior experience, but it might be best to watch this video if you haven’t used node-red before: https://www.youtube.com/watch?v=3AR432bguOY

What are we going to do?

We will set up a simple actionable notification to turn off a light in the house; if the light successfully turns off, then we’re going to send a second notification to your phone to let you know that the light successfully turned off.

If you’d rather import the template instead of follow this tutorial, see the section labeled Import Flow

Let’s get started!

  1. Open up the Node-RED WEB UI; as of this article (home assistant 2022.6), you would navigate to settings -> Add-ons -> Node-RED -> Open WEB UI. I’d recommend enabling Node-RED in the sidebar by clicking on “Show in the sidebar”
  2. Create a new Flow in node-red by clicking the + button near the top right of the page. I named mine Actionable Notification Template.
  3. Add the inject Node
  4. Add the change Node
    1. Change the title of the change node to “Set Title and Message”
    2. Change msg.payload to msg.message
    3. Change “to the value” to “Turn off light?”
    4. On the bottom left in “Edit Change Node”, add an item
    5. Change msg.payload to msg.title
    6. Change “to the value” to “Turn off light test”
    7. Your change node should look like this:
  1. Add a call service node
    1. Set the domain to “notify”
    2. Set the service to the entity for your mobile phone; in my case, it’s mobile_app_dan_samsung
    3. in the data dropdown, click JSON and add the below code:
{
    "message": "{{message}}",
    "title": "{{title}}",
    "data": {
        "actions": [
            {
                "action": "TURN_OFF_LIGHT",
                "title": "Set"
            },
            {
                "action": "IGNORE_LIGHT",
                "title": "Ignore"
            }
        ],
        "persistent": true,
        "tag": "persistent"
    }
}

Few notes on the above code: persistent notification means that at least on Android, you will not be able to swipe the notification away, and one of the two options needs to be selected.

The first title “Set” will be displayed as a way to set the device, the action should be changed for each actionable notification you create. You can add more options, but normally there is only enough room for 3 or 4 actions.

  1. Wire the 3 nodes together so it looks like this

Now that we have a way of sending a notification to the phone, we need a way to listen for actions (IE the button you press on the mobile app notification)

  1. Add the events.all Node
    1. Change the name to “All Mobile App Notification Actions”
    2. Set the Event Type to “mobile_app_notification_action
    3. Click the add button and set the message box to “event_type”, so it now says “msg.event_type”
    4. Select the dropdown and use “J: Expression”
    5. Set the field to “$outputData(“eventData”).event_type”

Your events: all Node should now look like this

  1. Add a switch node
    1. Under Property, change msg.payload to msg.payload.event.action
    2. Using the options we created from step 5 (call service node), we’re going to listen for the following
      1. TURN_OFF_LIGHT
      2. IGNORE_LIGHT
    3. Wire the events.all Node to the switch node

Your switch node should look like this:

  1. Add a Call Service Node
    1. Choose a light you would like to shut off, in this example I’m using an office light.
    2. In my case, I’d set the domain to light, the service to turn off, and then for the entity, I will select the office light. I want to use turn_off over toggle as I don’t want the light to toggle on.
    3. Wire the switch node to the call service node (use the top option on the switch node)
  2. Add a Current State Node
    1. Wire the Call Service Node to the Current State Node
    2. Title: Is the light off
    3. For the entity, you want to check the light you set in step 9, in my case, it will be light.office_light
    4. You will want to check “If State” is off
  1. Add a delay node with a fixed delay of 5 seconds. Note: Other devices such as locks may need more time
  2. Set your flow so that if the current state node is false, then wire it to the delay node
    1. Wire the output of the delay node back to the start of the current state node, what this will do is check to see if the device status has changed after a set amount of time (in this case 5 seconds). Your output should look like this:
  1. Create a Change Node
    1. Change “Set” to msg.message
    2. Change “to the value” to “light is turned off”
    3. Use the add button at the bottom of the change node
    4. Change the second “Set” to msg.title
    5. In my case, I’m going to change “to the value” to “Office Light”
    6. Wire the true value from the Current State Node to the Change Node
  1. Create a Call services node
    1. Wire the Change Node to the Call Service Node
    2. Title: Set Title and Message
    3. Set the domain to notify
    4. Set the service to the entity for your mobile phone, in my case it’s mobile_app_dan_samsung
    5. Change the data to “{}JSON”
    6. Add the below code
{
    "message": "{{message}}",
    "title": "{{title}}",
    "data": {
        "channel": "Alarm",
        "priority": "high",
        "ttl": 0
    }
}

Your flow should look as follows:

Try the flow by clicking on the grey box next to the Inject Node, you should receive a notification, you may need to “drop down” the notification to see the “Set” or “Ignore” options.

After you click on “Set”, the light you setup in step 9 should turn off, and you should receive a second notification letting you know that the light is indeed off.

Just export the flow!

If you don’t want to follow the above tutorial, you can import the below code into node-red and modify it.

Things you will have to modify:

  1. The call service node on the top right of the flow, so that the device points to your phone. You may also wish to change the title from “Notify Dan Phone”
  2. The call service node in the middle of the flow will need to change the entity specifically
  3. Current state node on the bottom right, you will need to change the device so it points to your phone, and may also wish to change the title.
[{"id":"96dd39fdae667f20","type":"tab","label":"Actionalable Notifcation Template","disabled":false,"info":"","env":[]},{"id":"ca1ee58e8537e8e9","type":"change","z":"96dd39fdae667f20","name":"Set Title and Message","rules":[{"t":"set","p":"message","pt":"msg","to":"Turn off light?","tot":"str"},{"t":"set","p":"title","pt":"msg","to":"Turn off light test","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":100,"wires":[["825395d1c0798abc"]]},{"id":"825395d1c0798abc","type":"api-call-service","z":"96dd39fdae667f20","name":"Notify Dan Phone","server":"2e31528c.f3973e","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_dan_samsung","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{message}}\",\"title\":\"{{title}}\",\"data\":{\"actions\":[{\"action\":\"TURN_OFF_LIGHT\",\"title\":\"Set\"},{\"action\":\"IGNORE_LIGHT\",\"title\":\"Ignore\"}],\"persistent\":true,\"tag\":\"persistent\"}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":100,"wires":[[]]},{"id":"f8127f4fe83a9869","type":"server-events","z":"96dd39fdae667f20","name":"All Mobile App Notification Actions","server":"2e31528c.f3973e","version":1,"event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":220,"y":180,"wires":[["c454db84e01eb54a"]]},{"id":"c454db84e01eb54a","type":"switch","z":"96dd39fdae667f20","name":"","property":"payload.event.action","propertyType":"msg","rules":[{"t":"eq","v":"TURN_OFF_LIGHT","vt":"str"},{"t":"eq","v":"IGNORE_LIGHT","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":180,"wires":[["cfa74a72b91007e8"],[]]},{"id":"cfa74a72b91007e8","type":"api-call-service","z":"96dd39fdae667f20","name":"Turn off LIght","server":"2e31528c.f3973e","version":5,"debugenabled":false,"domain":"light","service":"turn_off","areaId":[],"deviceId":[],"entityId":["light.office_light"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":610,"y":180,"wires":[["66dfbb89cd2e482a"]]},{"id":"66dfbb89cd2e482a","type":"api-current-state","z":"96dd39fdae667f20","name":"Is the light off?","server":"2e31528c.f3973e","version":3,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","entity_id":"light.office_light","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":860,"y":180,"wires":[["00baa760c0814417"],["144285fe99c71b29"]]},{"id":"144285fe99c71b29","type":"delay","z":"96dd39fdae667f20","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1020,"y":240,"wires":[["66dfbb89cd2e482a"]]},{"id":"00baa760c0814417","type":"change","z":"96dd39fdae667f20","name":"Set Title and Message","rules":[{"t":"set","p":"message","pt":"msg","to":"Light is turned off","tot":"str"},{"t":"set","p":"title","pt":"msg","to":"Office light","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":180,"wires":[["ea8c051ca30cc83b"]]},{"id":"ea8c051ca30cc83b","type":"api-call-service","z":"96dd39fdae667f20","name":"Notify Dan Phone (Priority)","server":"2e31528c.f3973e","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_dan_samsung","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{message}}\",\"title\":\"{{title}}\",\"data\":{\"channel\":\"Alarm\",\"priority\":\"high\",\"ttl\":0}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1400,"y":180,"wires":[[]]},{"id":"dfcd16f4a2fa1495","type":"inject","z":"96dd39fdae667f20","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":470,"y":100,"wires":[["ca1ee58e8537e8e9"]]},{"id":"2e31528c.f3973e","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

If you have any questions or issue with this tutorial, please leave a comment and I’ll try my best to reply to you!

10 comments On Create simple, actionable notifications with Home Assistant using Node-RED and the Home Assistant Companion App

  • Step 7.3, I don’t see an “add” button Ironically, I had already setup something similar back when it was “ios” stuff with categories, the json is slightly different now, and the call service is just under notify instead… But my old listner stuff is somehow still picking it up, it only has ios.notification_action_fired as the event type.

  • Oh Dan I celebrate you my friend! :_)
    I’ve been looking for a long time how to successfully implement “Actionable Notifications” with Nodered. Thanks to you, I can now use it in many of my projects and understand it to a large extent.
    Thank you for this!!

    However, I have a question: what do these commands do?

    “data”: {
    “channel”: “Alarm”,
    “priority”: “high”,
    “ttl”: 0

  • Hi, I love your tutorial!

    There are just a couple of things I don’t quite understand. If I want to make “different” actions for different types of notifications from turning a light on or off, to turning an alarm on or off, I should add different switch later to All Mobile App Notification Actions with the actions of each notification, no? Is there a way to link each switch to each type of “notification” ?

    On the other hand, is there any option that if, for example, I turn off a light, if I do not activate the notification, after x time a certain action is executed? And then on the other hand, is it possible that if it is during a time slot eg: 9am to 10pm the actions of the notifications can decide them, but from 12pm I get notifications with the option, but in itself after that time the actions after x minutes are performed alone ?

    I know my question may be a bit complex.

    Thank you very much for your tutorial

  • This does not work for me. I have followed the exact same steps in this and two additional tutorials (all the same steps), but I never get any events when selecting an action.

    • Are you getting notifications to your phone when using a simple inject node? Do the various options you created show up?
      If you are getting notifications, are you getting anything on the events: all node? Are you filtering on “mobile_app_notification_action” ?

  • Thanks, Dan. A very useful example which helped me translate what I’d read on doing this in ‘HA automation’ YAML into Node-RED. BTW. I used a Wait node instead of a Delay loop – just a preference.

  • Worked perfectly. Thanks for the great tutorial.

  • Thank you for your tutorial.
    About using notifications with a WearOS 4 (xiaomi watch 2):
    – sending notifications directly to the smartwatch, I didn’t find a way to see actions buttons
    – sending notifications to the smartphone, they also appear on the watch, and removing <> from the Json, you’ll get the action buttons on the watch too.
    I don’t know why, but the persistent parameter definitely inhibits buttons from appearing on WearOS notifications.
    tag, channel, importance, can be used without problems.

Leave a reply:

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Site Footer

Sliding Sidebar