Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Nathan Southgate
Published © GPL3+

Control Raspberry Pi (Linux device) from Alexa

Run scripts on your RPi/Linux device when voice commands are issued to Alexa. An AWS account is needed but the free tier is used (no cost).

IntermediateFull instructions provided3 hours16,065
Control Raspberry Pi (Linux device) from Alexa

Things used in this project

Story

Read more

Schematics

Summary

Summary of project, any python script can be ran on the RPi after a voice command

Repo for the strip lights

Code

Lambda Function

Python
The script to be used and customised in the Lambda function, the 'intent's and messages need to be customised and matched with the Alexa skill and the code running on the Pi
import boto3
  
# Below you need to add in your access key, access secret, rgion and sqs queue url
  
access_key = "This can be found in the downloaded .csv file"
access_secret = "This can be found in the downloaded .csv file"
region ="eu-west-1"
queue_url = "This can be found when looking at the SQS queue, https://..."
  
# you should not need to change the following unless you know what your doing.
  
def build_speechlet_response(title, output, reprompt_text, should_end_session):
   return {
       'outputSpeech': {
           'type': 'PlainText',
           'text': output
       },
       'card': {
           'type': 'Simple',
           'title': "SessionSpeechlet - " + title,
           'content': "SessionSpeechlet - " + output
       },
       'reprompt': {
           'outputSpeech': {
               'type': 'PlainText',
               'text': reprompt_text
           }
       },
       'shouldEndSession': should_end_session
   }
def build_response(session_attributes, speechlet_response):
   return {
       'version': '1.0',
       'sessionAttributes': session_attributes,
       'response': speechlet_response
   }
def post_message(client, message_body, url):
   response = client.send_message(QueueUrl = url, MessageBody= message_body)
def lambda_handler(event, context):
   client = boto3.client('sqs', aws_access_key_id = access_key, aws_secret_access_key = access_secret, region_name = region)
   intent_name = event['request']['intent']['name']
  
# The following needs to be customised
# The intent names shown below are linked with intents created in the custom Alexa Skill.
# The 'post_message' relates to the SQS queue 
# The 'message' line is the message/response that Alexa will speak back to you  
  
   if intent_name == "LightsOn":
       post_message(client, 'on', queue_url)
       message = "Lounge Lights will now turn on"
   elif intent_name == "LightsOff":
       post_message(client, 'off', queue_url)
       message = "Lounge Lights will now turn off"
   elif intent_name == "LightsRed":
       post_message(client, 'red', queue_url)
       message = "Lounge Lights will change to red"
   elif intent_name == "LightsGreen":
       post_message(client, 'green', queue_url)
       message = "Lounge Lights will now change to green"
   elif intent_name == "LightsBlue":
       post_message(client, 'blue', queue_url)
       message = "Lounge Lights will now change to blue"
   elif intent_name == "LightsTest":
       post_message(client, 'test', queue_url)
       message = "Lounge Lights will now run a test sequence"
   else:
       message = "Sorry but I do not understand that request"
  
   speechlet = build_speechlet_response("Mirror Status", message, "", "true")
   return build_response({}, speechlet)
0

Raspberry Pi

Python
This code needs to run on the Pi, when ran it will login to AWS and check the SQS queue for a message that is listed in this script, when matched it will run the corresponding Python script. This is set to check fro 60 seconds. You could extend this but you are best to schedule this to run every X seconds so that you do not exceed the 1,000,000 requests that are allowed per month on the free tier in AWS
import boto3
import os
import time
  
access_key = "Access key from the csv file"
access_secret = "Access seret from the csv file"
region = "the region where the SQS queue is - found in the queue url"
queue_url = "SQS Queue URL, https://sqs....."
  
def pop_message(client, url):
response = client.receive_message(QueueUrl = url, MaxNumberOfMessages = 10)
  
#last message posted becomes messages
message = response['Messages'][0]['Body']
receipt = response['Messages'][0]['ReceiptHandle']
client.delete_message(QueueUrl = url, ReceiptHandle = receipt)
return message
  
client = boto3.client('sqs', aws_access_key_id = access_key, aws_secret_access_key = access_secret, region_name = regi$
  
waittime = 20
client.set_queue_attributes(QueueUrl = queue_url, Attributes = {'ReceiveMessageWaitTimeSeconds': str(waittime)})
  
time_start = time.time()
while (time.time() - time_start < 30):
print("Checking...")
try:
message = pop_message(client, queue_url)
print(message)
if message == "on":
os.system("python /home/pi/LEDScripts/LED_on.py")
elif message == "off":
os.system("python /home/pi/LEDScripts/LED_off.py")
elif message == "blue":
os.system("python /home/pi/LEDScripts/LED_blue.py")
elif message == "red":
os.system("python /home/pi/LEDScripts/LED_red.py")
elif message == "green":
os.system("python /home/pi/LEDScripts/LED_green.py")
elif message == "test":
os.system("python /home/pi/LEDScripts/LED_test.py")
except:
pass

Repo for addressable leds

Credits

Nathan Southgate
1 project • 3 followers
Thanks to Ben Egan.

Comments