Voice con­trol your dig­i­tal pho­to frame with Ama­zon Echo, MQTT, and Node-RED


In this arti­cle, I will explain how to Alexa-voice con­trol your dig­i­tal pic­ture frame using Node-RED and the MQTT pro­to­col. Node-RED is a pro­gram­ming tool for wiring togeth­er Inter­net of Things hard­ware devices, APIs and online ser­vices.

It is an alter­na­tive to using Home Assis­tant which I have explained in this arti­cle.

The advan­tage of using Node-RED is that unlike Home Assis­tant, it can run on the same Rasp­berry Pi as your dig­i­tal pic­ture frame, it is much lighter and eas­i­er to set up, and it doesn't require a sub­scrip­tion to the Nabu Casa online ser­vice.

In con­junc­tion with the Ama­zon Alexa app, you can go much fur­ther than just voice con­trol­ling your dig­i­tal pic­ture frame. But in this arti­cle, I am going to focus on how to turn the dis­play of your dig­i­tal frame on and off using your voice.

Intro­duc­ing Node-RED

Node-RED is a flow-based pro­gram­ming tool that orig­i­nal­ly emerged as a hob­by project in IBM's Emerg­ing Tech­nol­o­gy Ser­vices group.

It began as a proof-of-con­­cept for visu­al­iz­ing and manip­u­lat­ing map­pings between MQTT top­ics and quick­ly grew into a gen­er­al solu­tion for con­nect­ing Inter­net of Things hard­ware.

It is very pop­u­lar in the Home Automa­tion space and can be uni­ver­sal­ly applied for con­trol­ling hard­ware of all sorts.

After it was open-sourced in 2013, more and more peo­ple dis­cov­ered its "mag­ic".

And "mag­ic" it is because "pro­gram­ming" Node-RED is a mat­ter of drag­ging and con­nect­ing ele­ments. It can be learned in no time, uses only mod­est sys­tem resources and has a wide fol­low­er-ship that keeps devel­op­ing add-ons to expand its use­ful­ness to all kinds of areas.

Installing Node-RED on your Rasp­berry Pi

Tested with Raspbian Buster July 2019
Note: The vcgencmd display_power 0 seems currently broken on the Raspberry Pi 4 but works fine with the other models.
You need to have at least one Gen. 2 Echo model in your network for the device discovery to work.

The instal­la­tion can be car­ried out on all Rasp­berry Pi mod­els includ­ing the Pi Zero, 2, 3 and 4 is very sim­ple with a script pro­vid­ed by the Node-RED team. This script can also be used to upgrade an exist­ing instal­la­tion when a new release is avail­able.

Con­nect to your Rasp­berry Pi via Ter­mi­nal. As always, when you install new soft­ware, make sure that your instal­la­tion is up to date with

sudo apt update && sudo apt upgrade -y

After com­ple­tion, enter this line:

bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)

The Node-RED instal­la­tion runs on auto-pilot

To launch Node-RED at boot, you will have to install it as a sys­tem ser­vice:

sudo systemctl enable nodered.service

Reboot your Pi.

Enter­ing Node-RED

To access Node-RED, open a brows­er win­dow of a com­put­er in the same net­work and enter


so for exam­ple

If you are enter­ing this infor­ma­tion direct­ly in Chrome on your Pi, then sim­ply type


You will be greet­ed by a screen like this:

Say hel­lo to Node-RED

By default, the Node-RED edi­tor is not secured and any­one who can access its IP address can access the edi­tor and deploy changes. This may be ok for your home net­work, but I rec­om­mend you pro­tect your­self by fol­low­ing this guide.

The under­ly­ing log­ic of Node-RED is this: The ele­ments on the left are the Nodes. A com­bi­na­tion of Nodes is a Sequence. When you have one or more Sequences in a tab, this is called a Flow.

Install add-on for Alexa voice con­trol

We need to install one add-on in Node-RED to make our nodes show up as a local device in the Ama­zon Alexa app.

Click on the top right Ham­burg­er Menu and select "Man­age palette".

Click on the "Install" tab, search for "node-red-con­trib-alexa-local",

and select "install".

For more infor­ma­tion on this mod­ule, look here.

Set­ting up the MQTT bro­ker

The com­mu­ni­ca­tion between Alexa and your dig­i­tal pic­ture frame is based on the light­weight mes­sag­ing pro­to­col MQTT. This has become the de-fac­­to stan­dard for the com­mu­ni­ca­tion between Inter­net-of-Things hard­ware.

The key terms in MQTT speak are "top­ic, mes­sage, pub­lish, and sub­scribe".

"Top­ic" is some­thing you want to par­tic­i­pate in, "pub­lish" when you make a state­ment con­cern­ing a top­ic, and "sub­scribe" is when you want to receive all state­ments around a top­ic. The con­tent of these com­mu­ni­ca­tion activ­i­ties is called "mes­sages".

An MQTT bro­ker is like a post office where these mes­sages are received and dis­trib­uted.

The MQTT bro­ker can be local­ly installed or accessed through an online ser­vice. I like to use the free Cloud­MQTT ser­vice because it has a great user inter­face which is very use­ful in the debug­ging process.

Get a "Cute Cat" account. It's free and comes with every­thing you need for our pur­pose.

Installing MQTT on the dig­i­tal pic­ture frame

It's time to get the dig­i­tal pic­ture frame part ready to lis­ten to MQTT mes­sages.

Enter in Ter­mi­nal

sudo pip3 install paho-mqtt

We need a Python script which turns the dig­i­tal pic­ture frame dis­play on or off. It lis­tens to the top­ic "frame/red/display" and turns the mon­i­tor on when the mes­sage is "on" and off when the mes­sage is "off".

Cre­ate a new file and paste the below con­tent in it. Name the file "red_monitor_cloudmqtt.py".

  1. #!/usr/bin/env python3
  3. import paho.mqtt.client as mqtt
  4. import subprocess
  6. def hdmi_on():
  7.     CONTROL = "vcgencmd"
  8.     CONTROL_BLANK = [CONTROL, "display_power", "1"]
  9.     subprocess.call(CONTROL_BLANK)
  11. def hdmi_off():
  12.     CONTROL = "vcgencmd"
  13.     CONTROL_BLANK = [CONTROL, "display_power", "0"]
  14.     subprocess.call(CONTROL_BLANK)
  16. def on_connect(client, userdata, flags, rc):
  17.   print("Connected to MQTT broker")
  19. def on_message(client, userdata, msg):
  20.     print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
  21.     if msg.payload.decode() == "on":
  22.         hdmi_on()
  23.     elif msg.payload.decode() == "off":
  24.         hdmi_off()
  25.     else:
  26.         pass
  28. client = mqtt.Client()
  29. client.username_pw_set( "User" , "Password" )
  30. client.connect( "m23.cloudmqtt.com", 17905, 60)
  31. client.subscribe( "frame/red/display" , qos=0)
  32. client.on_connect = on_connect
  33. client.on_message = on_message
  34. client.loop_forever()

In this script enter the para­me­ters for your Cloud­MQTT account in line 29 and 30 which you will find under "Instance Info". The Port is the nor­mal Port, not the SSL Port.

Cute as a cat

We want the script to be launched at boot and restart­ed should a net­work fail­ure occur.


sudo nano /lib/systemd/system/cloudmqtt.service

In the edi­tor, paste this text

Description=Cloudmqtt Service
ExecStart=/usr/bin/python3 /home/pi/red_monitor_cloudmqtt.py

Save and exit. Then enter in Ter­mi­nal

sudo chmod 644 /lib/systemd/system/cloudmqtt.service
sudo systemctl daemon-reload
sudo systemctl enable cloudmqtt.service

Cre­at­ing the sequences in Node-RED

We are now cre­at­ing the two sequences in Node-RED that trig­ger the MQTT mes­sages which tell our Rasp­berry Pi to turn the screen on or off.

Go back to the Node-RED brows­er win­dow by enter­ing:


Locate the node "alexa local" and drag it to the left half. Then locate the node "mqtt out" under Out­put - the one with the speak­er sym­bol on the right.

Com­bine the two nodes by draw­ing a line between them.

Dou­ble click on the "alexa local" node and enter "TDPF-dis­­­play-on" under "Name". Click "Done".

Dou­ble click on the "mqtt out" node. Enter your Cloud­MQTT Serv­er and your port. Under the Secu­ri­ty tab, enter your user name and pass­word.

Below the serv­er, enter the "Top­ic" as "frame/red/display". Select QoS (Qual­i­ty of Ser­vice) as "0". Leave the rest emp­ty and click "Done".

Cre­ate a sec­ond sequence with "alexa local" and "mqtt out" by drag­ging the ele­ments below the first ones and com­bin­ing them. Dou­ble click on the "alexa local" node and enter "TDPF-dis­­­play-off" under "Name" and repeat the steps as above for the MQTT node.

Sequenc­ing nodes

Click on "deploy" in the top right cor­ner. Now your flow (the con­tent in the tab) becomes active.

Cre­at­ing a rou­tine in the Ama­zon Alexa app

Get your mobile phone and open the Ama­zon Alexa app. Tap on the ham­burg­er menu in the top left cor­ner.

Tap on "Add Device", scroll to the bot­tom, tap "Oth­er", and "Dis­cov­er devices". Alter­na­tive­ly, you can say "Alexa, dis­cov­er my devices".

This will take about a minute.

Tap on "Devices" on the bot­tom row and then "All Devices" in the top row. Tap "Choose device" to see if they have been found.

Tap on "Home" and on the ham­burg­er menu again, then "Rou­tines". Cre­ate a new rou­tine by tap­ping on the top right "+" sign. Tap on "When this hap­pens" and then on "Voice". Com­plete the sen­tence like "Pic­ture Frame on".

Then add an action, "Smart Home", "Con­trol Device", scroll the list and look for "TDPF-dis­­­play-on". Select "Pow­er" and set it to "On". Tap "Next" and "Save".

Repeat the same process with "TDPF-dis­­­play-off". But this time, select "Pow­er" and set it to "Off".

Wait a minute for the Ama­zon serv­er to refresh and then test the rou­tines by tap­ping on the play icon and see if the screen turns on or off.

If that works, speak your com­mand to Alexa.


Although we went through a num­ber of steps, the over­all set­up isn't very hard.

And this is just one exam­ple of how you can use Node-RED in con­junc­tion with Ama­zon Alexa to voice con­trol your pho­to frame.

You can let Alexa speak a mes­sage once a com­mand has been exe­cut­ed or cre­ate new com­mands. You can also use it for home automa­tion tasks, all on the same Rasp­berry Pi that is hid­den behind your dig­i­tal pic­ture frame.

The next release of the Pi3D script will fea­ture a num­ber of com­mands that are ready for voice con­trol with the MQTT pro­to­col. So it makes a lot of sense to try this sim­ple dis­play on/off com­mand and build on this set­up going for­ward.