There’s one big problem when sending an actionable notification from Home Assistant to the Home Assistant companion app: If your phone is not connected to your local network (where your home assistant server is running), selecting an action button of an actionable notification won’t have any effect since no connection between the app and your Home Assistant server can be established.
Imagine that you have an automation that detects that you left your home while you didn’t turn off the heating. Maybe it’s on purpose since you are just walking the dog for 10 minutes but maybe you are going on a weekend trip for the next few days and just forgot to turn it off. Wouldn’t it be great if Home Assistant could ask you if it should turn off the heating with an actionable push notification?
Unfortunately this won’t work on default since actionable notification do not work with the Home Assistant companion app when your phone is not connected to your local network. Thankfully there are several different ways to make actionable notifications work from wherever you are.
There is an important security advantage for push notification based solutions (Telegram Bot integration and Simplepush). It’s that with actionable notifications you most likely only expose a small part of your smart home to the internet while all other solutions involve trusting a third party and/or your technical abilities with your whole smart home.
In this article you will learn how easy it is to send actionable notifications from Home Assistant that work from everywhere. You will also learn how to run Node-RED with your Home Assistant instance.
With Simplepush Actions there is a new way to send actionable notifications from Home Assistant that doesn’t require setting up a VPN or opening up your Home Assistant instance to the internet. It’s also much cheaper ($9.99/year vs. $65/year) than subscribing to Nabu Casa (a service that allows you to control your Home Assistant from anywhere).
Simplepush is an app to receive actionable push notifications on your iOS and Android devices. With the free version you are able to send and receive five actionable notifications per month.
If you are already familiar with how to setup Home Assistant to work with Node-RED, feel free to skip the Setup Node-RED for Home Assistant section and go directly to the Actionable Notification in Home Assistant section.
You can learn more on how to send actionable notifications from Node-RED (without Home Assistant) in this blog post.
It is also possible to send actionable push notifications to Simplepush without Node-RED. All you need is the ability to make HTTP requests (e.g. with curl). With Feedback Actions you immediately receive a feedback id after sending an actionable notification. With your feedback id you can query the state of your actionable notification (learn more in this blog post).
If you prefer to use native Home Assistant automations, make sure to check out this article on how to send actionable notifications and react to actions with native Home Assistant automations.
Node-RED is a low-code tool for visual application development in the browser.
While Home Assistant excels at bringing all your home automation devices under one platform and keeping the state of those devices, Node-RED is still the better choice when it comes to creating your home automations (at least when your automations get a bit more complicated).
There are two different ways to install Node-RED:
This guide will focus on how to install Node-RED if you don’t run Home Assistant Supervised or Home Assistant OS. If you are running Home Assistant Supervised or Home Assistant OS things are a bit easier since you can install Node-RED as an add-on directly from the Home Assistant frontend.
Please follow the official guide on how to install Node-RED.
Once Node-RED is running, go to the Palette Manager (Node-RED Settings → Manage palette) and install:
node-red-contrib-home-assistant-websocket
Alternatively install it from the command line with npm:
$ cd ~/.node-red
$ npm install node-red-contrib-home-assistant-websocket
# restart Node-RED
Put an events: all
node into your flow an open its settings.
Once you open the settings, you will see a server field. If you click the pencil icon right next to it, you can enter the base url of your Home Assistant instance and an access token.
Long-Lived Access Token
and click Create Token
. You can then use whatever name you want (e.g. “Node-RED”).Your Node-RED server is now connected to your Home Assistant and you should have a bunch of Home Assistant nodes in your nodes list on the left.
You can delete the event: all
node from your flow.
In this section you will see how to install the node-red-contrib-simplepush
package which is required to send actionable notifications from Node-RED to Simplepush.
In addition you will learn from examples how to create Node-RED flows that send actionable notifications and how to make them trigger subflows (e.g. home automations).
Now that you have a running Node-RED server, which is connected to Home Assistant, everything that is left before we can start creating flows is the installation of the node-red-contrib-simplepush package in Node-RED.
Once again you can either install the package with the Node-RED Palette Manager or with npm from the command line:
$ cd ~/.node-red
$ npm install node-red-contrib-simplepush
# restart Node-RED
If you haven’t installed Simplepush on your iOS or Android device yet, now is the time to do it. After installing the app, it will immediately show you your private Simplepush key. This key is the only information that is required for receiving actionable notifications on your device.
Since you have five free actionable notifications per month, there is no need to purchase the subscription to try out the following examples.
This example flow sends an actionable notification when the inject node is triggered. The actionable notification will have two actions: “on” and “off”. Depending on which action is selected, a light will be turned on or off.
As you can see in the picture above, defining two actions in the settings of the Simplepush node creates two outputs on the node.
The timeout
field in the node settings defines a timeout in seconds after which Node-RED will stop listening for actions being selected.
In addition an exception will be thrown (feedback timeout error) that could be intercepted.
If you don’t want a timeout at all, set the timeout to 0
.
The top node output of the Simplepush node fires if the “on” action is selected in the actionable notification and the bottom one will fire if the “off” action is selected. If you hover over the node outputs of your Simplepush node, a popup will show up and tell you which output corresponds to which action.
The “Light on” and “Light off” nodes are “call service” nodes. You can find the “call service” node in the Home Assistant section of the node list on the left.
Just select the domain, the service and the entity according to the device that you want to call and you are good to go.
You can import this example flow from the following JSON:
Imagine you live in a household of three and your noisy washing machine is connected to Home Assistant. Wouldn’t it be cool to create an automation where the washing machine only starts if a majority of the three people in the household agree that it’s okay to start it?
With Node-RED and Simplepush this works even if nobody is at home.
We start by creating Simplepush nodes for each person. For each person add the same feedback actions (“yes” and “no”) in the settings. Choose a timeout that suits you. If you don’t know how timeouts work, take a look at the first example flow where we go into the details of timeouts.
Now connect all Simplepush nodes to an inject node. The inject node triggers the Simplepush nodes which in turn send out the defined actionable notifications. In reality you would most likely want to have a different trigger (e.g. a sensor or a button that is pushed).
Join nodes are used to join together the input of several inputs into a single message.
For the use case we have in mind, we need the join node to only fire once all three actions where selected.
For this to be the case, we need to set “After a number of message parts” to 3
in the settings of the join node.
We also want to set the “to create” field to an Array
.
This has the effect that all selected actions will be returned from the join node as an array.
// Example output of join node when set to "an Array"
[0: "yes", 1: "no", 2: "yes"]
Everything that is left to do is to create a function node that decides which action won. The output of the function node should therefore either be “yes” or “no” depending on whether there are more “yes” or “no” in the input array that was passed to the function node.
To achieve this, create a function node with the following code:
// Function node to get voting result from array of votes
msg.payload = mode(msg.payload);
return msg;
function mode(arr){
return arr.sort((a,b) =>
arr.filter(v => v===a).length
- arr.filter(v => v===b).length
).pop();
}
From here you could forward the voting result to a switch node that turns on the washing machine if the voting result is “yes”. In this example we created a debug node to print the result to the debugger.
You can import this example flow from the following JSON:
When an action is selected, the Simplepush node outputs a message that contains the selected action as its payload (msg.payload
).
In addition the message also includes metadata. For example msg.actionDeliveredAt
is a timestamp describing the exact time the information about the action reached the Simplepush backend (this can differ from msg.actionSelectedAt
since an action can be selected while the device is offline).
In this example flow we will make use of msg.actionSelectedAt
to decide who is first in selecting an action from an actionable notification.
First we fire off two actionable notifications to two different persons with an inject node.
In order to be able to identify which actionable notification corresponds to which person, we make use of the change
node that sets a person
property.
If an action gets selected, it will be passed to a join
node.
The join
node then waits for both actions to be selected before it forwards the joined result.
Make sure to select “a key/value Object” on the “to create” field. This will create an object where the person property is the key and the Simplepush node output is the value.
The last step is to decide who won. We do that with a function
node that contains the following javascript code and gets its input from the join node.
var min = Object.keys(msg.payload).map(function(k) {
return msg.payload[k];
}).reduce(function(a, b) {
return b.actionSelectedAt < a.actionSelectedAt ? b : a;
});
msg.payload = min;
return msg;
This javascript code returns the object (at msg.payload
) that has the smallest actionSelectedAt
property.
If you don’t know upfront which actions your actionable notification should include, you can pass an array of strings to the Simplepush node input at runtime.
The action array has to be included via the actions
property of the input message.
Since in this case it is decided at runtime which actions will be included in an actionable notification, there is only one output on the Simplepush node (unlike when you define actions in the settings).
To demonstrate how to define actions at runtime, we create an inject node that forwards the current timestamp to a function node.
The function node forwards msg.actions = ['action 1']
to our Simplepush node if the injected timestamp is divisible by two and msg.actions = ['action 2']
otherwise.
The function node can be implemented with the following javascript code:
var isDivisible = msg.payload % 2 === 0;
if (isDivisible) {
msg.actions = ['action 1'];
} else {
msg.actions = ['action 2'];
}
// No timeout
msg.timeout = 0;
return msg;
We set msg.timeout
to zero which disables timeouts. The default would be a timeout after 180 seconds if no action was selected.
When an action is selected, the action (either “action 1” or “action 2”) and its metadata (e.g. msg.actionSelectedAt
which contains the timestamp of the exact date when the action was selected) is written to the single output of the Simplepush node.