I need to be careful with sunburn, so we installed an electronic sun-blind that extends out from the house to cover part of our garden. I was excited to hear from the people who we bought the sun-blind from, that we could control it with Alexa. It was not mentioned we would need to buy a £250 device to link the blind with Alexa. I decided to build my own device for £30.
This was straight a straight forward project and just required connecting up simple circuitry to control the buttons on the remote (that I took to pieces and soldered wires onto, to allow me to control its push buttons via the pizero).
I used Flask-Ask on another pizero (see my pi-parking project) that in turn contacted this pizero to control the relays which in turn controlled the sunblinds. I used Quart, not Flask, because I needed to be able to stop the blinds rolling out after 0-10 seconds (specified by the Alexa command), which required Async to allow the app to immediately reply to the Alexa backend, and then, at a later time, stop the blinds from moving. I guess I could have used Celery-Beat to achieve the same goal, but using aync was the simpler option.
I'll write another blog on setting things up in the Alexa-console backend. It was tricky and not that intuitive. Despite that, it was a far better experience than I had setting up a similar project (pi-parking) but with google-assistant. I perhaps spent an hour setting up the Alexa backend here, compared to 4, on that other project.
import asyncio
import platform
from quart import Quart, Response
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pins = [18, 17, 15, 14]
blinds_stop = pins[0]
blinds_out = pins[1]
blinds_in = pins[2]
GPIO.setup(pins, GPIO.OUT)
WINDOWS = platform.system() == 'Windows'
app = Quart(__name__)
config = {}
app.config.from_mapping(config)
port = 5000
locked = False
@app.route('/all_off')
async def all_off():
for _pin in pins:
GPIO.output(_pin, GPIO.HIGH)
return 'all off'
for _pin in pins:
GPIO.output(_pin, GPIO.HIGH)
async def blinds_action(blind):
GPIO.output(blind, GPIO.LOW)
time.sleep(1)
GPIO.output(blind, GPIO.HIGH)
async def stop_later(s):
print('here')
global locked
if not locked:
time.sleep(s)
locked = False
await stop()
@app.route('/out', defaults={'s': None})
@app.route('/out/<int:s>')
async def out_for(s=None):
await blinds_action(blinds_out)
if s:
asyncio.ensure_future(stop_later(s))
return 'out'
@app.route('/in', defaults={'s': None})
@app.route('/in/<int:s>')
async def in_for(s=None):
await blinds_action(blinds_in)
if s:
asyncio.ensure_future(stop_later(s))
return 'in'
@app.route('/stop')
async def stop():
await blinds_action(blinds_stop)
return Response('stop')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=port)
I have got a lot of joy out of this project. I've a spare photo-frame and am considering what to do for my next arty pi project :)