Introduction: Control Living Room With Alexa and Raspberry Pi

Control your living room TV, lights, and Fan with Alexa (Amazon Echo or Dot) and Raspberry Pi GPIO.

Step 1: Initial Setup

I used a Raspberry Pi 2 and a Raspbian Jessie image downloaded from https://www.raspberrypi.org/downloads/raspbian/

Once logged in, enter the following commands to install the required packages and python libraries:

sudo apt-get update && sudo apt-get upgrade -y<br>sudo apt-get install python2.7-dev python-dev python-pip
sudo pip install Flask flask-ask 
sudo apt-get install lirc

Step 2: Setup Ngrok

Visit https://ngrok.com/download and get the latest Linux ARM release as a zip and unzip inside the home directory:

unzip /home/pi/ngrok-stable-linux-arm.zip 

Open a new terminal and enter the following command:

sudo ./ngrok http 4000

Open another new terminal and enter the following command:

sudo ./ngrok http 4500

Open third new terminal and enter the following command:

sudo ./ngrok http 5000

Step 3: Python Script for Light Switch Control

Open a new terminal session and create a new python file named light_control.py:

nano light_control.py

Copy/paste the following code into the new file:

from flask import Flask<br>from flask_ask import Ask, statement, convert_errors
import RPi.GPIO as GPIO
import logging
import os
GPIO.setmode(GPIO.BCM)
app = Flask(__name__)
ask = Ask(app, '/')
logging.getLogger("flask_ask").setLevel(logging.DEBUG)
@ask.intent('LightControlIntent', mapping={'status': 'status'})
def light_control(status):
    try:
        pinNum = 27
    except Exception as e:
        return statement('Pin number not valid.')
    GPIO.setup(pinNum, GPIO.OUT)
    if status in ['on', 'high']:    GPIO.output(pinNum, GPIO.LOW)
    if status in ['off', 'low']:    GPIO.output(pinNum, GPIO.HIGH)
    return statement('Turning {} the Living Room Lights'.format(status))
if __name__ == '__main__':
    port = 4000 
    app.run(host='0.0.0.0', port=port)

Save and close the file.

Start the flask server with:

sudo python light_control.py<br>

Leave both ngrok and light_control.py running

Step 4: Python Script for Fan Control

Open a new terminal session and create a new python file named fan_control.py:

nano fan_control.py

Copy/paste the following code into the new file:

from flask import Flask
from flask_ask import Ask, statement, convert_errors
import RPi.GPIO as GPIO
import logging
import os
GPIO.setmode(GPIO.BCM)
app = Flask(__name__)
ask = Ask(app, '/')
logging.getLogger("flask_ask").setLevel(logging.DEBUG)
@ask.intent('FanControlIntent', mapping={'status': 'status'})
def fan_control(status):
    try:
        pinNum = 22
    except Exception as e:
        return statement('Pin number not valid.')
    GPIO.setup(pinNum, GPIO.OUT)
    if status in ['on', 'high']:    GPIO.output(pinNum, GPIO.LOW)
    if status in ['off', 'low']:    GPIO.output(pinNum, GPIO.HIGH)
    return statement('Turning {} the Living Room Lights'.format(status))
if __name__ == '__main__':
    port = 4500 
    app.run(host='0.0.0.0', port=port)

Save and close the file.

Start the flask server with:

sudo python fan_control.py

Leave both ngrok, light_control.py, and fan_control.py running

Step 5: Installing and Configuring the LIRC Package

In order to control the TV you must configure a pin on the Raspberry Pi to generate infrared (IR) signals for your specific TV. Open terminal and enter the following command to install an LIRC package that emulates the infrared signals of many remote controls.

sudo apt-get install lirc

Next, you need to enable and configure the lirc_rpi kernel module. To do so, open modules in the Nano editor

sudo nano /etc/modules

Add the lines below to the file (Make sure that the gpio_out_pin parameter points to the pin controlling the IR LED):

lirc_dev
lirc_rpi gpio_out_pin=17

Next, open the hardware.conf filein Nano as before with sudo:

sudo nano /etc/lirc/hardware.conf

Add the following configuration to the file:

LIRCD_ARGS="--uinput"
LOAD_MODULES=true

DRIVER="default"

DEVICE="/dev/lirc0"

MODULES="lirc_rpi"

LIRCD_CONF=""

LIRCMD_CONF=""

Now, reboot the Raspberry Pi:

sudo reboot

Step 6: Python Script for TV Control

Open a new terminal session and create a new python file named ir_control.py:

nano ir_control.py

Go to http://lirc-remotes.sourceforge.net/remotes-table...

Find a remote that is compatible with your TV. In my case I have a Sanyo TV that works with the sanyo-tv01 config file. Once you find a file that supports your TV open it and look through the command options.

Copy/paste the following code into the new file and replace sanyo-tv01 with the file name that works with your TV. Also ensure that the tv commands are supported by your TVs config file; You may have to modify the KEY_POWER, KEY_VIDEO, KEY_VOLUMEUP, KEY_VOLUMEDOWN, and KEY_MUTE commands to work correctly with your TV's config file:

from flask import Flask<br>from flask_ask import Ask, statement, convert_errors
import RPi.GPIO as GPIO
import logging
import os
GPIO.setmode(GPIO.BCM)
app = Flask(__name__)
ask = Ask(app, '/')
logging.getLogger("flask_ask").setLevel(logging.DEBUG)
@ask.intent('GPIOControlIntent', mapping={'status': 'status'})
#'pin': 'pin'})
def tv_function(status):
    if status in ['turn on']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_POWER")
	return statement('Turning on the TV')
    elif status in ['turn off']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_POWER")
        return statement('Turning off the TV')    
    elif status in ['change input']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VIDEO")
        os.system("irsend SEND_ONCE sanyo-tv01 KEY_VIDEO")        
        return statement('Changing input on the TV')    
    elif status in ['increase volume']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEUP")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEUP")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEUP")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEUP")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEUP")        
	return statement('Increasing Volume on the TV')    
    elif status in ['decrease volume']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEDOWN")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEDOWN")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEDOWN")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEDOWN")
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_VOLUMEDOWN")        
	return statement('Decreasing Volume on the TV')    
    elif status in ['mute']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_MUTE")
        return statement('Muting the TV')    
    elif status in ['unmute']:    
	os.system("irsend SEND_ONCE sanyo-tv01 KEY_MUTE")
        return statement('Unmuting the TV')
    else:
	return statement('Remote function not found.')
if __name__ == '__main__':
    port = 5000 
    app.run(host='0.0.0.0', port=port)

Save and close the file.

Start the flask server with:

sudo python ir_control.py

Leave all three ngrok terminal windows, light_control.py, fan_control.py, and ir_control.py running

Step 7: Login to AWS Account

First create or login to your AWS Developer Account and open your list of Alexa Skills.

Step 8: TV Alexa Skill Setup

Select "Add a New Skill".

Set the Skill Name to 'Trigger TV' and the Invocation Name to the word(s) you want to use to activate the skill.

Click 'Next' to continue.

Copy/paste the following into the 'Intent Schema' box:

{  "intents": [{
      "slots": [{
          "name": "status",
          "type": "TV_Function"
        },
        {
          "name": "amount",
          "type": "AMAZON.NUMBER"
        }],
      "intent": "GPIOControlIntent"
    }]
}

Next, click 'Add Slot Type'

Enter TV_Function in the 'Enter Type' field.

Enter the following values in the 'Enter Values' field:

turn on
turn off
change input
increase volume
decrease volume
mute
unmute

Next, Copy/paste the following into the 'Sample Utterances' box:

GPIOControlIntent {status}

GPIOControlIntent {status} by {amount}

Click 'Next' to continue.

Select 'HTTPS' as the Service Endpoint Type and select a region.
Enter the ngrok URL from step 2 and click 'Next'. The URL should be something like:

https://ed6ea04d.ngrok.io

Click 'Next' to continue and press 'Save'.

Step 9: Lights Alexa Skill Setup

Close the open skill and select "Add a New Skill".

Set the Skill Name to 'Lights Control' and the Invocation Name to the word(s) you want to use to activate the skill.

Click 'Next' to continue. Copy/paste the following into the 'Intent Schema' box:

{
    "intents": [{
      "slots": [{
          "name": "status",
          "type": "LIGHTS_CONTROL"
        }],
      "intent": "LightsControlIntent"
    }]
}

Next, click 'Add Slot Type'.

Enter "LIGHTS_CONTROL" in the 'Enter Type' field.

Enter the following values in the 'Enter Values' field:

on
off

Next, Copy/paste the following into the 'Sample Utterances' box:

LightsControlIntent turn {status}

Click 'Next' to continue. Select 'HTTPS' as the Service Endpoint Type and select a region. Enter the ngrok URL from step 2 and click 'Next'. The URL should be something like:

https://ed6ea04d.ngrok.io

Click 'Next' to continue and press 'Save'.

Step 10: Fan Alexa Skill Setup

Close the open skill and select "Add a New Skill".

Set the Skill Name to 'Fan Control' and the Invocation Name to the word(s) you want to use to activate the skill.

Click 'Next' to continue.

Copy/paste the following into the 'Intent Schema' box:

{
  "intents": [{
      "slots": [{
          "name": "status",
          "type": "FAN_CONTROL"
        }],
      "intent": "FANControlIntent"
    }]
} 

Next, click 'Add Slot Type'.

Enter "FAN_CONTROL" in the 'Enter Type' field.

Enter the following values in the 'Enter Values' field:

on
off 

Next, Copy/paste the following into the 'Sample Utterances' box:

FANControlIntent turn {status} 

Click 'Next' to continue. Select 'HTTPS' as the Service Endpoint Type and select a region. Enter the ngrok URL from step 2 and click 'Next'. The URL should be something like:

https://ed6ea04d.ngrok.io

Click 'Next' to continue and press 'Save'.

Step 11: Build the Ciruit

Connect the circuit as shown in the diagram. I used a JBtek 8 Channel DC 5V Relay Module to connect to my homes AC 120v line and ground.

Step 12: Alexa Commands

Now the following commands can be spoken to Alexa to control you living room.