Created a REST Switch to control a Pi zero W running a calendar display

I built a kitchen calendar based on: https://www.hanselman.com/blog/HowToBuildAWallMountedFamilyCalendarAndDashboardWithARaspberryPiAndCheapMonitor.aspx
running Dakboard, and the family loves it. I had been using his rpi-hdmi.sh script and cron to turn the display on and off based on when we were usually home/away. Well, this break has put that to the test and I kept looking over at the display, expecting it to be on, except we would have normally been at work. I had just implemented a basic presence detection, and thought hey, why can’t I use HA to turn the display on and off when we’re home? I first tried an SSH shell command, but I wanted to get the status, and that doesn’t work so well over SSH. Then I learned about REST Switches, and I had used the excellent code from Bit-River (Bluetooth presence detection without Raspberry Pi 3) for Bluetooth tracking on the same Pi Zero W. I used to program in a previous life, and figured I’d cobble together something based on that. So, I learned flask, brushed up on Python, and drove my husband mad asking all kinds of questions about it (he programs for a living), and finally came up with what you see here. A switch that I can use in automations (or from the UI) to turn the display on and off.

in a switch.yaml:

- platform: rest
  resource: http://IPADDRESS:8000/api/status/display
  name: Calendar Display
  body_on: "on"
  body_off: "off"
  is_on_template: '{{ value == "on" }}'

The code is:

from flask import Flask,request,make_response
import subprocess
app = Flask(__name__)

@app.route('/api/status/display', methods=['POST'])
def hdmi_change():

	state = None
	state = request.get_data()
#	if state is None:
#		print ("state failure")
#	print ("state is: ", state)

	if state == b'on':
		# Turn on the display
		subprocess.call(['/home/pi/rpi-hdmi.sh', 'on'])
		print ("turning on display")
		return ("on") 
	elif state == b'off':
		# Turn off the display
		subprocess.call(['/home/pi/rpi-hdmi.sh', 'off'])
		print ("turning off the display")
		return ("off")
	else:
		abort (404)



@app.route('/api/status/display', methods=['GET'])
def return_status():
	# Return state 
	proc = subprocess.Popen(['/home/pi/rpi-hdmi.sh', 'status'], stdout=subprocess.PIPE)
	if proc.stdout.read() == b'on\n':
		print ("returning on")
#		response = make_response("on")
		return("on")
	else:
		print ("returning off")
	#	response = make_response("off")
		return("off")
#	response.headers['Content-Type'] = 'text/plain'
#	return response
  

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=False)

I’m inordinately proud of myself for figuring this all out. The REST switch isn’t that well documented, and it doesn’t seem to have a large following, but it was perfect for what I needed.

3 Likes