In this article, I will show you how to use Home Assistant's WiFi-based presence detection system to turn your digital picture frame off when nobody is in the house - and back on again when somebody comes home - using the MQTT protocol to communication between the devices.
It is also the basis for Amazon Echo or Google Voice control of your digital picture frame and a great deal of other smart home automation scripts.
Presence detection is a significant subject in home automation and is very relevant for the owner of a digital picture frame.
The life expectancy of your frame will increase when you turn off the display when it's not needed, and your energy costs will go down. And if both results can be achieved in a way that doesn't compromise on convenience, then it's a no brainer to do it.
At the center of it all is the smartphone. You can assume that everyone in your family will have at least one device and won't leave home without it for a longer time.
There are three technologies that you can use with your smartphone: WiFi, Bluetooth or geofencing. Geofencing is the use of GPS data of your phone to create a virtual geographic boundary to trigger a response when you enter or leave a pre-defined area.
I initially tested geofencing on my iPhone in combination with IFTTT, the service that aims to get all your apps and devices talking to each other.
I had it set up so when somebody would leave the house it would register on the digital picture frame. When nobody at home, it would turn off the frame display.
And when a person was getting near 50m of the house, the frame would lighten up again.
This sounded to me like a great approach because it works independently of a WiFi system. However, in practice, geofencing often didn't work for me both for leaving and coming back. It was either too slow or completely unresponsive.
After a few months of testing, I concluded that it was too unreliable for my use case.
I haven't given Bluetooth presence detection a thorough test yet, but given the limited range of Bluetooth, I am a bit skeptical if it would work well in a larger house. But out of curiosity, I may give it a try in the future.
Presence detection with WiFi, however, is something I have tested for over four months now and I am very pleased with its reliability and responsiveness.
It has become my favorite presence detection method, and I will show you how you can use it to turn your digital picture frame on or off automatically.
The summary of how this set up works is this:
The WiFi router knows which devices are connected at home even if they are asleep.
It typically takes a minute to recognize a new device and about 10 minutes until a non-present device is being dropped from the network.
The device tracker feature in Home Assistant will act upon the change of a network state of one of the specified devices through an automation script and trigger a response.
The response in my case is a message broadcast via MQTT which the digital picture frame picks up and in turn, triggers a Python script to turn the frame on or off.
Home Assistant Device trackers
The following instructions assume that you have installed HASS.IO (Home Assistant) on a Raspberry Pi, NUC or even NAS.
It also assumes that your WiFi router is on the list of devices that are compatible with the device tracker of Home Assistant. This list includes many devices, and it is getting longer with every new bi-weekly update release of Home Assistant, so the chances are good that your WiFi router is on it.
We have never had a better WiFi system (says my wife so this must be right). Indeed, the Unify setup is so much better than everything we had before in terms of performance, stability and seamless roaming between base stations.
Setting up a device tracker in Home Assistant is easy although it first looks a bit complicated. But I'll walk you through.
To use this device tracker in your installation, add the following to your Home Assistant configuration.yaml file:
# Unifi Presence Detection device_tracker: - platform: unifi_direct host: 192.168.135.51 #(change to IP of your base station) username: unifi_ap_username password: unifi_ap_password interval_seconds: 10 consider_home: 180 new_device_defaults: track_new_devices: False hide_if_away: True
If you have a controller like me for two or more Ubiquity Unify direct AP, then you must add every access point as a platform point individually.
Make sure that username and password are the SSH device password, not the login for your Unify controller.
There may be a way to access the controller directly, but I never got it to work, but the three access points individually work very well together for device tracking.
Restart Home Assistant.
If you haven't used a device tracker yet, a new file called known_devices will be created.
Open this file and check if your device appears. Although you have put "track_new_devices: False", every device is recorded in this file, but the tracking status is set to "False".
Find the smartphones that you want to track for your presence detection. If you have many devices, this may be a bit tricky a first because you may only see the MAC number.
The MAC (Media Access Control) number is a hardware identification number that uniquely identifies each device on a network.
To find out your device number, you either look it up on your phone. If you see an item under General - Info (on iPhones) called "WiFi address" that looks like d4:a4:3d:38:34:30 then you found it. Alternatively, you can see the MAC address in your WiFi router.
In known_devices.yaml change the track tag to "true" for all tracked smartphones.
So it will look like
wolfgang-iPhone: name: Wolfgang mac: D4:A4:3D:38:34:30 icon: picture: /local/wolfgang.png hide_if_away: true track: true
The picture is optional but looks nice in Home Assistant. To add it, place a 192 x 192 px PNG file in the "www" directory. Yes, "local" is not "www" but trust me, it will work.
Restart Home Assistant and check the device states. It will say "home" when the device is connected to the home WiFi and "not_home" when not.
In the front end of Home Assistant, probably Lovelace, define the entities like in this example:
entities: - device_tracker.person1 - device_tracker.person2 entity: device_tracker title: Presence type: entities
To test if it works, turn off the wifi on your phones and wait a few minutes. Sometimes it can be swift; sometimes it takes up to 10 minutes to drop a device from the network scan. Finding a new device is much faster.
We have one last setting to do in Home Assistant, but before we can come to this, we must first install our MQTT setup.
The MQTT broker
MQTT stands for MQ Telemetry Transport and is an extremely simple and lightweight messaging protocol. Originally conceived to work with minimal network bandwidth, it is ideal for the Internet-of-Things world and the communication between many small and low-powered devices. This is why it has become so popular for Home Automation systems.
MQTT works, to put it very simply, like a post office. People are sending letters to each other, but they have to always get to the central post office where they are being distributed.
The key terms are "topic, message, publish and subscribe". Topic is something you want to participate in, publish is when you make a statement concerning a topic, and subscribe is when you want to receive all statements around a topic. The content of these communication activities is called "messages". The post office in MQTT speak is the "broker".
This is as far I will go in this article, there are lots of good tutorials on this subject on the internet. Although MQTT is a simple protocol, it can be a potent communication tool.
The first thing to install is the MQTT broker.
In Home Assistant you can install the Mosquitto broker add-on, an open source MQTT broker. In theory, this should work well but I had my share of problems with it, so I reverted to a free hosted message broker CloudMQTT.
What I like about CloudMQTT is its WebSocket UI which is most helpful for debugging an MQTT setup with several devices. Get a "Cute Cat" account, it's free and comes with everything you need.
One could argue that having your own private post office is the safer alternative because the MQTT broker doesn't leave your Raspberry Pi, but I don't see any issues with the Swedish company 84codes which is behind CloudMQTT. Your messages are still not visible to anybody but yourself.
As always, make sure that you use strong and unique passwords.
Installing MQTT on your digital picture frame
The following instructions assume that you have read my article "How to set up your Raspberry Pi for your digital picture frame".
In Terminal connect to your digital picture frame with
sudo pip install paho-mqtt
Now we need a Python script which turns the digital picture frame display on or off.
You can download it here or copy and paste it. It listens to the topic "frame/monitor" and turns the monitor on when the message is "ON" and off when the message is "OFF". Name the file "monitor_cloudmqtt.py".
#!/usr/bin/env python3 import paho.mqtt.client as mqtt import subprocess def hdmi_on(): CONTROL = "vcgencmd" CONTROL_BLANK = [CONTROL, "display_power", "1"] subprocess.call(CONTROL_BLANK) print ( "I turned the screen on!" ) def hdmi_off(): CONTROL = "vcgencmd" CONTROL_BLANK = [CONTROL, "display_power", "0"] subprocess.call(CONTROL_BLANK) print ( "I turned the screen off!" ) def on_connect(client, userdata, flags, rc): print("Connected to MQTT broker") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) if msg.payload.decode() == "ON": hdmi_on() client.publish("frame/monitor", "ON") elif msg.payload.decode() == "OFF": hdmi_off() client.publish("frame/monitor", "OFF") else: pass def on_subscribe(client, userdata, mid, granted_qos): print("Subscribed to topic : " + str(mid) +" with QoS" + str(granted_qos)) client = mqtt.Client() client.username_pw_set( "User" , "Password" ) client.connect( "m23.cloudmqtt.com", 17905, 60) client.subscribe( "frame/monitor/set" , qos=0) client.on_connect = on_connect client.on_message = on_message client.loop_forever()
Check the following settings which you will find in your CloudMQTT account details under "Instance Info".
client.username_pw_set( "User" , "Password" )
client.connect( "Server", Port, 60)
This script needs to run on start-up, so we'll add it to the crontab.
Add a line in the editor
@reboot sleep 60 && screen -dmS MQTT python3 /home/pi/monitor_cloudmqtt.py
The purpose of the sleep command is to delay the execution of our MQTT Python script for 60 seconds until the boot process is fully through and networking has been established.
Setting up MQTT in Home Assistant configuration.yaml
Add this paragraph in configuration.yaml:
# CloudMQTT mqtt: broker: m23.cloudmqtt.com port: 17905 username: username password: your-password
# MQTT Switch switch: - platform: mqtt name: "Digital Picture Frame" icon: mdi:panorama state_topic: "frame/monitor" command_topic: "frame/monitor/set" availability_topic: "frame/monitor/available" payload_on: "ON" payload_off: "OFF" state_on: "ON" state_off: "OFF" qos: 0 retain: true
Finally, set up the entity switch for the digital picture frame in the Lovelace UI.
Restart Home Assistant and reboot your digital picture frame. Congratulations, you can now control your digital picture frame through Home Assistant!