Control your digital picture frame with Home Assistent's WiFi presence detection and MQTT

By February 25, 2019 May 22, 2019 DIY Instructions, Home Assistant
Home Assis­tant is one of the most excit­ing devel­op­ments in the home automa­tion space. Found­ed by Dutch­man Paulus Schout­sen only a few years ago, it has tak­en the world by storm and is dri­ven by a world­wide com­mu­ni­ty of tin­ker­ers and DIY enthu­si­asts.

In this arti­cle, I will show you how to use Home Assistant's WiFi-based pres­ence detec­tion sys­tem to turn your dig­i­tal pic­ture frame off when nobody is in the house - and back on again when some­body comes home - using the MQTT pro­to­col to com­mu­ni­ca­tion between the devices.

It is also the basis for Ama­zon Echo or Google Voice con­trol of your dig­i­tal pic­ture frame and a great deal of oth­er smart home automa­tion scripts.

Home Alone

Pres­ence detec­tion is a sig­nif­i­cant sub­ject in home automa­tion and is very rel­e­vant for the own­er of a dig­i­tal pic­ture frame.

The life expectan­cy of your frame will increase when you turn off the dis­play when it's not need­ed, and your ener­gy costs will go down. And if both results can be achieved in a way that doesn't com­pro­mise on con­ve­nience, then it's a no brain­er to do it.

At the cen­ter of it all is the smart­phone. You can assume that every­one in your fam­i­ly will have at least one device and won't leave home with­out it for a longer time.

There are three tech­nolo­gies that you can use with your smart­phone: WiFi, Blue­tooth or geofenc­ing. Geofenc­ing is the use of GPS data of your phone to cre­ate a vir­tu­al geo­graph­ic bound­ary to trig­ger a response when you enter or leave a pre-defined area.

I ini­tial­ly test­ed geofenc­ing on my iPhone in com­bi­na­tion with IFTTT, the ser­vice that aims to get all your apps and devices talk­ing to each oth­er.

I had it set up so when some­body would leave the house it would reg­is­ter on the dig­i­tal pic­ture frame. When nobody at home, it would turn off the frame dis­play.

And when a per­son was get­ting near 50m of the house, the frame would light­en up again.

This sound­ed to me like a great approach because it works inde­pen­dent­ly of a WiFi sys­tem. How­ev­er, in prac­tice, geofenc­ing often didn't work for me both for leav­ing and com­ing back. It was either too slow or com­plete­ly unre­spon­sive.

After a few months of test­ing, I con­clud­ed that it was too unre­li­able for my use case.

I haven't giv­en Blue­tooth pres­ence detec­tion a thor­ough test yet, but giv­en the lim­it­ed range of Blue­tooth, I am a bit skep­ti­cal if it would work well in a larg­er house. But out of curios­i­ty, I may give it a try in the future.

Pres­ence detec­tion with WiFi, how­ev­er, is some­thing I have test­ed for over four months now and I am very pleased with its reli­a­bil­i­ty and respon­sive­ness.

It has become my favorite pres­ence detec­tion method, and I will show you how you can use it to turn your dig­i­tal pic­ture frame on or off auto­mat­i­cal­ly.

Feeling home

The sum­ma­ry of how this set up works is this:

The WiFi router knows which devices are con­nect­ed at home even if they are asleep.

It typ­i­cal­ly takes a minute to rec­og­nize a new device and about 10 min­utes until a non-present device is being dropped from the net­work.

The device track­er fea­ture in Home Assis­tant will act upon the change of a net­work state of one of the spec­i­fied devices through an automa­tion script and trig­ger a response.

The response in my case is a mes­sage broad­cast via MQTT which the dig­i­tal pic­ture frame picks up and in turn, trig­gers a Python script to turn the frame on or off.

Home Assistant Device trackers

The fol­low­ing instruc­tions assume that you have installed HASS.IO (Home Assis­tant) on a Rasp­berry Pi, NUC or even NAS.

It also assumes that your WiFi router is on the list of devices that are com­pat­i­ble with the device track­er of Home Assis­tant. This list includes many devices, and it is get­ting longer with every new bi-week­ly update release of Home Assis­tant, so the chances are good that your WiFi router is on it.

Although I have a FritzBox 7490 act­ing as a DSL modem, the house WiFi is made up of three Ubiq­ui­ty Unifi direct AP meshed togeth­er with a Uni­fy con­troller.

We have nev­er had a bet­ter WiFi sys­tem (says my wife so this must be right). Indeed, the Uni­fy set­up is so much bet­ter than every­thing we had before in terms of per­for­mance, sta­bil­i­ty and seam­less roam­ing between base sta­tions.

Set­ting up a device track­er in Home Assis­tant is easy although it first looks a bit com­pli­cat­ed. But I'll walk you through.

I'll base my instruc­tions on the Ubiq­ui­ty Uni­fy direct Access Points but on this page, you will instruc­tions for many WiFi router devices.

To use this device track­er in your instal­la­tion, add the fol­low­ing to your Home Assis­tant 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 con­troller like me for two or more Ubiq­ui­ty Uni­fy direct AP, then you must add every access point as a plat­form point indi­vid­u­al­ly.

Make sure that user­name and pass­word are the SSH device pass­word, not the login for your Uni­fy con­troller.

There may be a way to access the con­troller direct­ly, but I nev­er got it to work, but the three access points indi­vid­u­al­ly work very well togeth­er for device track­ing.

Restart Home Assis­tant.

If you haven't used a device track­er yet, a new file called known_devices will be cre­at­ed.

Open this file and check if your device appears. Although you have put "track_new_devices: False", every device is record­ed in this file, but the track­ing sta­tus is set to "False".

Find the smart­phones that you want to track for your pres­ence detec­tion. If you have many devices, this may be a bit tricky a first because you may only see the MAC num­ber.

The MAC (Media Access Con­trol) num­ber is a hard­ware iden­ti­fi­ca­tion num­ber that unique­ly iden­ti­fies each device on a net­work.

To find out your device num­ber, you either look it up on your phone. If you see an item under Gen­er­al - Info (on iPhones) called "WiFi address" that looks like d4:a4:3d:38:34:30 then you found it. Alter­na­tive­ly, you can see the MAC address in your WiFi router.

In known_devices.yaml change the track tag to "true" for all tracked smart­phones.

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 pic­ture is option­al but looks nice in Home Assis­tant. To add it, place a 192 x 192 px PNG file in the "www" direc­to­ry. Yes, "local" is not "www" but trust me, it will work.

Restart Home Assis­tant and check the device states. It will say "home" when the device is con­nect­ed to the home WiFi and "not_home" when not.

In the front end of Home Assis­tant, prob­a­bly Lovelace, define the enti­ties like in this exam­ple:

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 min­utes. Some­times it can be swift; some­times it takes up to 10 min­utes to drop a device from the net­work scan. Find­ing a new device is much faster.

We have one last set­ting to do in Home Assis­tant, but before we can come to this, we must first install our MQTT set­up.

The MQTT broker

MQTT stands for MQ Teleme­try Trans­port and is an extreme­ly sim­ple and light­weight mes­sag­ing pro­to­col. Orig­i­nal­ly con­ceived to work with min­i­mal net­work band­width, it is ide­al for the Inter­net-of-Things world and the com­mu­ni­ca­tion between many small and low-pow­ered devices. This is why it has become so pop­u­lar for Home Automa­tion sys­tems.

MQTT works, to put it very sim­ply, like a post office. Peo­ple are send­ing let­ters to each oth­er, but they have to always get to the cen­tral post office where they are being dis­trib­uted.

The key terms 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 is 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". The post office in MQTT speak is the "bro­ker".

This is as far I will go in this arti­cle, there are lots of good tuto­ri­als on this sub­ject on the inter­net. Although MQTT is a sim­ple pro­to­col, it can be a potent com­mu­ni­ca­tion tool.

The first thing to install is the MQTT bro­ker.

In Home Assis­tant you can install the Mosquit­to bro­ker add-on, an open source MQTT bro­ker. In the­o­ry, this should work well but I had my share of prob­lems with it, so I revert­ed to a free host­ed mes­sage bro­ker Cloud­MQTT.

What I like about Cloud­MQTT is its Web­Sock­et UI which is most help­ful for debug­ging an MQTT set­up with sev­er­al devices. Get a "Cute Cat" account, it's free and comes with every­thing you need.

One could argue that hav­ing your own pri­vate post office is the safer alter­na­tive because the MQTT bro­ker doesn't leave your Rasp­berry Pi, but I don't see any issues with the Swedish com­pa­ny 84codes which is behind Cloud­MQTT. Your mes­sages are still not vis­i­ble to any­body but your­self.

As always, make sure that you use strong and unique pass­words.

Installing MQTT on your digital picture frame

The fol­low­ing instruc­tions assume that you have read my arti­cle "How to set up your Rasp­berry Pi for your dig­i­tal pic­ture frame".

In Ter­mi­nal con­nect to your dig­i­tal pic­ture frame with

ssh pi@IP-of-your-digital-picture-frame

Enter

sudo pip install paho-mqtt

Now we need a Python script which turns the dig­i­tal pic­ture frame dis­play on or off.

You can down­load it here or copy and paste it. It lis­tens to the top­ic "frame/monitor" and turns the mon­i­tor on when the mes­sage is "ON" and off when the mes­sage 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 fol­low­ing set­tings which you will find in your Cloud­MQTT account details under "Instance Info".

Adapt this para­graph

client.username_pw_set( "User" , "Password" )

and

client.connect( "Server", Port, 60)

This script needs to run on start-up, so we'll add it to the crontab.

crontab -e

Add a line in the edi­tor

@reboot sleep 60 && screen -dmS MQTT python3 /home/pi/monitor_cloudmqtt.py

The pur­pose of the sleep com­mand is to delay the exe­cu­tion of our MQTT Python script for 60 sec­onds until the boot process is ful­ly through and net­work­ing has been estab­lished.

Setting up MQTT in Home Assistant configuration.yaml

Add this para­graph in configuration.yaml:

# CloudMQTT
mqtt:
  broker: m23.cloudmqtt.com
  port: 17905
  username: username
  password: your-password

and

# 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

Final­ly, set up the enti­ty switch for the dig­i­tal pic­ture frame in the Lovelace UI.

Restart Home Assis­tant and reboot your dig­i­tal pic­ture frame. Con­grat­u­la­tions, you can now con­trol your dig­i­tal pic­ture frame through Home Assis­tant!