Smart Display Auto On/Off
You are currently viewing Smart Display Auto On/Off

I’ve always been interested in having a smart display in my apartment which will show me useful information and serve as a modern piece of decor. I created a nice looking page using DAKBoard but having to manually turn on my TV and select the right input made it seem pointless to use.

Due to a recent influx of free time I started looking into how to automate this process and discovered that you can use an HDMI connection to send commands to your TV from a Linux computer, such as the RaspberryPi which I had sitting around.

With that HDMI interface in mind I created a few tools to accomplish the automation I wanted:

  1. An IFTTT applet which looks at my Google Calendar for times to turn the TV on and off
  2. A Dropbox developer app so that I can use Dropbox as a buffer for the text files that serve as commands
  3. The Python application which will process commands in the Dropbox buffer and control the TV
Here is a sequence diagram of how it works:
 

And here is the Python script:

 

 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#! /usr/bin/python3
import os
import dropbox
import requests
import time
import subprocess
folderPath = '/IFTTT/Google Calendar'
onCommand = 'TV:On.txt'
offCommand = 'TV:Off.txt'
tvOnCommand = "echo 'on 0' | cec-client -s -d 1"
tvSetInput = "echo 'as 0' | cec-client -s -d 1"
tvOffCommand = "echo 'standby 0' | cec-client -s -d 1"
tvQueryPower = "echo 'pow 0' | cec-client -s -d 1"
TV_ON = 'power status: on'
TV_OFF = 'power status: standby'
dbx = dropbox.Dropbox('YOUR_DROPBOX_API_KEY')

def main():
    while True:
        update_tv_state()
        time.sleep(.1)
        #print("returned to main")

def is_tv_on():
    result = subprocess.check_output(tvQueryPower, shell=True, text=True)
    resultList= result.splitlines()
    print(resultList[1])
    if (resultList[1] == TV_ON):
        return True
    else:
        return False
    
def is_tv_off():
    result = subprocess.check_output(tvQueryPower, shell=True, text=True)
    resultList= result.splitlines()
    print(resultList[1])
    if (resultList[1] == TV_OFF):
        return True
    else:
        return False
    
def turn_tv_on():
    subprocess.check_output(tvOnCommand, shell=True, text=True)
    print("Turning TV ON")
    attemptCounter = 0
    while (not is_tv_on()):
        attemptCounter += 1
        print("in while")
        if(attemptCounter > 3):
            return False
    time.sleep(4)
    set_input_as()
    
def set_input_as():
    print("setting input")
    result = subprocess.check_output(tvSetInput, shell=True)        
def turn_tv_off():
    if (is_tv_off() is False):
        print("Turning TV OFF")
        subprocess.check_output(tvOffCommand, shell=True, text=True)
        return True
    else:
        print("TV Already off")
        return False
    
def update_tv_state():
    CurrentFiles = dbx.files_list_folder(folderPath).entries
    try:
        latestCommand = CurrentFiles[0].name
        latestDate = CurrentFiles[0].client_modified
        for entry in CurrentFiles:
            if(latestDate < entry.client_modified):
                latestDate = entry.client_modified
                latestCommand = entry.name
        #print("Most recent command was: " + latestCommand)
        if(latestCommand == 'TV:On.txt'):
            turn_tv_on()
            dbx.files_delete_v2(folderPath + '/TV:On.txt')
        if(latestCommand == 'TV:Off.txt'):
            turn_tv_off()
            dbx.files_delete_v2(folderPath + '/TV:Off.txt')
    except:
        print("Unrecognized or no command")
        pass



if __name__ == '__main__':
    main()

Leave a Reply