• First Steps
  • General
  • Projects
Facebook Twitter YouTube
Tutorials for Raspberry Pi Tutorials for Raspberry Pi
  • Hardware & GPIO
  • Sensors & Components
  • Scale
  • Cases
  • Fingerprint
  • Gas Sensor
  • Heartbeat
  • German
Tutorials for Raspberry Pi Tutorials for Raspberry Pi
Home»Home Automation»Develop Your Own Raspberry Pi Alexa Skill and Control Pi Remotely

Develop Your Own Raspberry Pi Alexa Skill and Control Pi Remotely

Facebook Twitter LinkedIn Tumblr Email Reddit
Eigenen Raspberry Pi Alexa Skill entwickeln und Pi fernsteuern
Share
Facebook Twitter LinkedIn Email Tumblr Reddit Telegram WhatsApp

Voice control is an increasingly important component in smart homes. For this purpose, Amazon provides skills that run on Amazon Echo Dot, Fire TV sticks, smartphones and other devices. In this way, Raspberry Pi Alexa skills can also be created in a simple manner.

The skills can be published optionally and even money can be made with them. In this tutorial, we will create an Alexa skill which will execute commands on our local Raspberry Pi. We will go through all the points of that process step by step.

Various other providers such as Google (“OK Google”), Apple (Siri) and Microsoft (Cortana) also have language assistants and offer opportunities to write your own skills. If you are interested, we can show those in future tutorials.

This tutorial includes building simple LED controls, but many other scenarios can be built through small adjustments.

Required Hardware Parts

The software runs completely on the Pi. We also need the hardware which will be operated by voice control. For this we will use the following:

  • Raspberry Pi
  • LEDs
  • Optimal: Resistors
  • a Power Supply (USB Type C)

An Amazon device with Alexa is also required. These are:

  • Echo Plus
  • Echo Dot
  • Fire TV Stick
  • Echo Show
  • alternatively: Alexa App for iOS or Android

 

Preparation and Raspberry Pi Programming

Before we create the actual Alexa skill, we have to set up and configure a few things. First of all, we need an Amazon developer account. We first create an account on developer.amazon.com or log in with the existing Amazon account.

Then we take care of the setup on the Raspberry Pi.

Connecting the Raspberry Pi Hardware and Installing the Software

Before you start the Pi, connect a simple LED with the long end to GPIO 17 and the short end to Ground. Here you can see the pin assignment:

Raspberry Pi GPIO Pin Assignment
Raspberry Pi GPIO Pin Assignment

Ideally, you can also connect a small resistor (220Ω) between Ground and the LED.

Since this example is very simple, I would like to give you some better project ideas:

  • change (and dim) LED strip effects via voice control
  • control a thermostat
  • water the garden on command
  • query the temperature of other rooms
  • start video recording from surveillance cameras
  • and much more

Installation

Now connect e.g. via SSH with the Raspberry Pi. First of all we install the required software. We use the Python packages Flask or Flask-Ask, which make it very easy to write Amazon Alexa skills:

python3 -m pip install Flask-Ask
pip3 install --upgrade setuptools
pip3 install 'cryptography<2.2'

As you can see, we used a version less than 2.2 of the package cryptography. With newer versions. there are often errors in connection with Flask.

Now let’s create the python file that contains our code:

sudo python3 alexaskill.py

This file has the following content:

Python
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
import logging
import os
 
from flask import Flask
from flask_ask import Ask, request, session, question, statement
import RPi.GPIO as GPIO
 
app = Flask(__name__)
ask = Ask(app, "/")
logging.getLogger('flask_ask').setLevel(logging.DEBUG)
 
STATUSON = ["on", "switch on", "enable", "power on", "activate", "turn on"] # all values that are defined as synonyms in type
STATUSOFF = ["off", "switch off", "disactivate", "turn off", "disable", "turn off"]
 
@ask.launch
def launch():
    speech_text = 'Welcome to the Raspberry Pi alexa automation.'
    return question(speech_text).reprompt(speech_text).simple_card(speech_text)
 
@ask.intent('LightIntent', mapping = {'status':'status'})
def Gpio_Intent(status,room):
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(17,GPIO.OUT)
    if status in STATUSON:
        GPIO.output(17,GPIO.HIGH)
        return statement('Light was turned on')
    elif status in STATUSOFF:
        GPIO.output(17,GPIO.LOW)
        return statement('Light was turned off')
    else:
        return statement('Sorry, this command is not possible.')
 
@ask.intent('AMAZON.HelpIntent')
def help():
    speech_text = 'You can say hello to me!'
    return question(speech_text).reprompt(speech_text).simple_card('HelloWorld', speech_text)
 
 
@ask.session_ended
def session_ended():
    return "{}", 200
 
 
if __name__ == '__main__':
    if 'ASK_VERIFY_REQUESTS' in os.environ:
        verify = str(os.environ.get('ASK_VERIFY_REQUESTS', '')).lower()
        if verify == 'false':
            app.config['ASK_VERIFY_REQUESTS'] = False
    app.run(debug=True)
 

Save the file with Ctrl + O and close the editor with Ctrl + X. Then we run the file:

python3 alexaskill.py

Accessibility Outside of the Local Network

We now have a Raspberry Pi server running, but this can only be accessed via the local network. It must be publicly accessible so that Amazon can call up our Raspberry Pi later.

We could either use a dDNS service and enable the ports in the router, or we could use ngrok. This has the advantage that we can save the configuration.

Open a new terminal (do not close the old one) and enter the following:

wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip
unzip ngrok-stable-linux-arm.zip

Afterwards we can start:

./ngrok http 5000

NgrokWe then need the second URL (https) for Amazon.

Attention: As a non-registered user, the connection will be reset after 8 hours and you will get a new URL. You can change this by registering and providing your token:

./ngrok authtoken <TOKEN>

It is also possible to choose the subdomain yourself. You can find more information about ngrok in the documentation.

./ngrok http -subdomain=myveryownamazonalexaskill 5000

 

By the way: We can also start both commands (Python script and ngrok) via autostart.

 

Setting up the Raspberry Pi Alexa Skill in the Amazon Developer Account

We press the “Create Skill” button in the Amazon Developer Console. Here we assign a name (e.g. “Raspberry Pi”), choose the language and the “Custom” model. The hosting method is “Provision your own”.  Then we click on “Create Skill” in the top right corner.

Create Raspberry Pi Alexa Skill - New Skill

Then we press the plus sign next to “Slot Types” (Interaction Models) and create a new type called “STATUS”:

Create Raspberry Pi Alexa Skill - Slot Type

For this we create two “values”. These are given the names “on” and “off” and we also define all possible synonyms (these are the same synonyms that are also specified in the Python script):

Amazon Alexa Skill Slot Values

As the last configuration step, we create an “intent” (click on the plus sign) with the name “LightIntent” (the same name which was also specified in the script):

Create Raspberry Pi Alexa Skill - Add Intent

In the lower part, we first add the “intent slot”. Here we choose the type “STATUS” and also call it “status” (lower case):

Raspberry Pi Alexa Skill Intent Slot

In the upper part, you can now enter all possible voice commands, such as “turn off the light”. By double-clicking on a word, you can replace it with the slot:

Raspberry Pi Alexa Skill Light Intent

Think about different combinations that you want to use later. Usually, the call is e.g. as following:

Alexa, tell Raspberry Pi, [turn on light / turn off light / …]

The second part is therefore important and should be defined in this part. Save the model and press “Build Model”.

Here again the generated JSON file. You can also just paste them in

JavaScript
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
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "raspberry pi",
            "modelConfiguration": {
                "fallbackIntentSensitivity": {
                    "level": "LOW"
                }
            },
            "intents": [
                {
                    "name": "AMAZON.FallbackIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "LightIntent",
                    "slots": [
                        {
                            "name": "status",
                            "type": "STATUS"
                        }
                    ],
                    "samples": [
                        "light {status}"
                    ]
                }
            ],
            "types": [
                {
                    "name": "STATUS",
                    "values": [
                        {
                            "id": "on",
                            "name": {
                                "value": "off",
                                "synonyms": [
                                    "switch on",
                                    "enable",
                                    "power on",
                                    "activate",
                                    "turn on"
                                ]
                            }
                        },
                        {
                            "id": "off",
                            "name": {
                                "value": "on",
                                "synonyms": [
                                    "switch off",
                                    "disactivate",
                                    "turn off",
                                    "disable",
                                    "turn off"
                                ]
                            }
                        }
                    ]
                }
            ]
        }
    }
}

 

Last but not least, we have to specify the server URL to which the commands are sent. To do this, click on “Endpoint” on the left, select HTTPs and paste the URL of ngrok into “Default Region”. Also, choose the following option: “My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority“.

Amazon Alexa Skill Endpoint

Don’t forget to save it.

 

Test the New Raspberry Pi Alexa Skill – Locally and on Amazon Echo Devices

We now want to test the Raspberry Pi Alexa Skill. There are various options for this, which we will go into. Ideally, both are carried out in succession:

1. Amazon Developer Console – Test

In the Developer Console, there is the possibility to send commands via voice recording or text under the tab “Test”. To do this, you have to allow your browser to use your microphone. You can see that command on the right side.

2. Live Testing on Amazon Echo (Dot), Fire TV Stick, etc.

We want our developed skill to run permanently on Amazon devices. To do this, first, we have to add all devices to our account. How this works is, among other things, described here. You can see all Alexa devices either in the smartphone app (Android, iOS) or in the Amazon dashboard.

You can also easily add new devices in the apps. As soon as the device is linked to the account, the skill can already be used.

https://tutorials-raspberrypi.de/wp-content/uploads/alexaskill.mp4

 

What projects do you have in mind? Further ideas and suggestions as comments are welcome.

Amazon Alexa Amazon Echo Amazon Fire TV Stick Featured home automation Home automation Houseautomation Smart Home speech detection
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
Previous ArticleRaspberry Pi KI: Objekterkennung mittels TensorFlow und Kamera
Next Article Raspberry Pi & Teachable Machine – Tensorflow Modelle für KI nutzen

Related Posts

Control all GPIOs with the Raspberry Pi REST API via Python

Using TensorFlow Lite with Google Coral TPU on Raspberry Pi 4

Raspberry Pi Samba Server: Share Files in the Local Network

Build Live Text Recognition with the Raspberry Pi (OCR)

26 Comments

  1. Nick Marino on 17. April 2020 23:40

    When I test this the py script just keeps returning “I’m sorry this command is not possible.”
    Checked everything many times.
    What am I missing?

    Reply
    • Felix on 18. April 2020 0:47

      You can see in the console what was sent from the Amazon API. Did it contain one of your phrases?

      Reply
  2. Arrow Lastname on 21. May 2020 1:37

    Great tutorial! However, I cannot seem to get it to work. I have followed the entire tutorial and I am using the exact JSON code provided. WHen I try a command such as “ask raspberry pi light on”, “tell raspberry pi light on” or even “open raspberry pi”, I get the response “There was a problem communicating with the requested skill”
    It does not seem to be accessing the ngrok link that I have set up on the pi, since I don’t see any change in the ngrok terminal, or the alexaskill.py terminal (which should log something if the link was accessed). What could I be doing wrong?

    Reply
    • Felix on 21. May 2020 20:39

      Can you manually try to reach your ngrok server (from inside and outside of your network)? This is where I would begin to search for the issue.

      Reply
      • Arrow Lastname on 28. May 2020 19:20

        Thank you for the reply. Yes, I can manually access the ngrok server by entering in the URL into a browser (both in and out of the local network). The browser in both cases reports “Method Not Allowed” and ngrok prints the two lines:
        GET /favicon.ico 404 NOT FOUND
        GET / 405 METHOD NOT ALLOWED

  3. Rafael Fonseca on 26. June 2020 18:36

    Hi.. it works like a charm. But how i can turn on off all GPIO just saying a word like turn TV ON or turn IRRIGATION ON?

    Need to change the python of alexa skill or start a lot of skills?

    Reply
  4. mark on 1. July 2020 3:55

    I’m getting this error when running – python3 alexaskill.py…
    Traceback (most recent call last):
    File “alexaskill.py”, line 5, in
    from flask_ask import Ask, request, session, question, statement
    ImportError: No module named ‘flask_ask’
    I installed python3 -m pip install Flask-Ask
    Also tried changing the from flask_ask import Ask, request, session, question, statement to ..
    from flask-ask import Ask, request, session, question, statement

    Reply
  5. John on 28. October 2020 21:30

    Says I need 3.5 or higher of Python to install anything but I have 3.7. Even running “Python –version” shows I have 3.7 so not sure how to resolve this.

    Reply
  6. Botond Geiszt on 12. November 2020 12:45

    There is something with the _ character, replace it with your own _

    Reply
  7. marco navarro on 26. November 2020 7:25

    can someone tell me where to insert te code please?

    Reply
    • marco navarro on 26. November 2020 7:33

      inside the plataform of amazon just after create the intent slot

      Reply
  8. Emmanuel Raju on 24. December 2020 11:28

    Great tutorial!
    I’m able to test it successfully through the simulator in the console. But failing to do so through a physical echo dot device. I keep getting “Sorry, I’m having trouble accessing your Raspberry Pi skill right now “. Could you please help me out with this?

    Reply
  9. John D Maag on 1. January 2021 22:18

    when i type sudo python3 alexaskill.py, i get python3: cant open file ‘alexaskill.py’: [Errno2] no such file or directory

    Reply
    • Jeremy Schneider on 7. December 2022 3:34

      I think the writer probably intended it to be something like `sudo nano alexaskill.py`. I think the `sudo` is probably unnecessary, too

      Reply
  10. bob on 15. February 2021 21:29

    Im unclear how to get the skill to run on the alexa.

    Reply
    • Tom on 12. August 2021 3:14

      No kidding! Did you get an answer?

      Reply
  11. Rich on 11. March 2021 13:00

    I Followed this guide but unfortunately i am receiving this error. Just like a lot of people in the comment section it doesn’t work.
    I hope someone can fix it 🙂
    error:
    ”’
    [2021-03-11 11:55:31,215] ERROR in app: Exception on / [POST]
    Traceback (most recent call last):
    File “/home/user/.local/lib/python3.8/site-packages/flask/app.py”, line 2446, in wsgi_app
    response = self.full_dispatch_request()
    File “/home/user/.local/lib/python3.8/site-packages/flask/app.py”, line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
    File “/home/user/.local/lib/python3.8/site-packages/flask/app.py”, line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
    File “/home/user/.local/lib/python3.8/site-packages/flask/_compat.py”, line 39, in reraise
    raise value
    File “/home/user/.local/lib/python3.8/site-packages/flask/app.py”, line 1949, in full_dispatch_request
    rv = self.dispatch_request()
    File “/home/user/.local/lib/python3.8/site-packages/flask/app.py”, line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
    File “/usr/local/lib/python3.8/dist-packages/flask_ask/core.py”, line 560, in _flask_view_func
    result = self._map_intent_to_view_func(self.request.intent)()
    File “/usr/local/lib/python3.8/dist-packages/flask_ask/core.py”, line 574, in _map_intent_to_view_func
    view_func = self._intent_view_funcs[intent.name]
    KeyError: ‘TVSourceIntent’
    127.0.0.1 – – [11/Mar/2021 11:55:31] “POST / HTTP/1.1” 500 –
    {
    “context”: {
    “Extensions”: {
    “available”: {
    “aplext:backstack:10″: {}
    }
    ”’

    Reply
  12. John Russell on 20. April 2021 15:14

    Your tutorial is excellent. I was able to learn enough by completing it to write my own Alexa skill with Python. My next step is to do the same thing in C++. Thanks for taking the time and effort to put this together.

    Reply
  13. Bill The Turnip on 29. July 2021 7:06

    Hello , great tutorial thanks for posting.
    A quick question I have is why go for Ngrok rather than the recomended (in alexa developemnt docs) AWS ? Just wondering..

    Reply
    • Jeremy Schneider on 7. December 2022 3:47

      There needs to be a way for the Alexa service (in the AWS cloud) to communicate with the program that has access to the GPIO hardware on the Raspberry Pi. The ngrok program must make a tunnel from the Pi to the ngrok servers. It then tells you the address of the endpoint at the ngrok servers. You give that ngrok endpoint to Alexa. Alexa then sends its commands to that endpoint at ngrok, which then sends the commands on to the local machine that can twiddle the GPIO bits. I think that if you just want to process data (say, look up meanings of baby names
      like “Alexa, what does the name Erica mean?”), that could be all done in the cloud, because it does not require any access to a local pi machine. Ngrok also nicely takes care of the certificate for the HTTPS communication that Alexa rightly requires.

      Reply
  14. Rocvar on 2. April 2022 9:55

    hi I ran the alexaskill.py program but getting this error message:

    aceback (most recent call last):
    File “/home/pi/alexaskill.py”, line 5, in
    from flask_ask import Ask, request, session, question, statement
    File “/usr/local/lib/python3.9/dist-packages/flask_ask/__init__.py”, line 9, in
    from .core import (
    File “/usr/local/lib/python3.9/dist-packages/flask_ask/core.py”, line 10, in
    from werkzeug.contrib.cache import SimpleCache
    ModuleNotFoundError: No module named ‘werkzeug.contrib’

    Any idea please on what is causing it?

    Thanks

    Reply
    • Steve O'Driscoll on 2. June 2022 1:16

      You can get around this my downgrading to the older version of werkzeug
      try
      pip3 uninstall Werkzeug
      then
      pip3 install Werkzeug==0.16.0

      Reply
    • Patrick on 31. July 2022 16:33

      Apply this command.
      It will solve your problem

      pip install https://github.com/johnwheeler/flask-ask/archive/master.zip

      Reply
  15. Patrick on 1. August 2022 23:13

    The installation went well.
    The setting of the skill was ok.
    I’m unable to apply a successfull command in the Test mode from the Amazon developer page.
    The answer is “There was a problem with the requested skill’s response” or “Sorry, I didn’t find a group or device named raspberry pi light”.
    Please note I’ve started alexaskill.py on the RPI3 first

    Any idea ?

    Reply
  16. Bob on 13. March 2023 0:22

    No comment on the author as all the other posters apparently had better luck, but something about the initial python package and pip package installs/upgrades totally trashed my entire python development environment. While I have some moderate experience with linux and python, I could find no solutions using google-foo to make repairs. Ended up wiping the disk (SD card actually since this was on an RPi) and restarting from scratch… hours lost (not days thankfully) and all prior projects thankfully backed up.

    Incidentally python was at 3.9 and pip at 20-something (pip no longer lets me do pip -V.

    Initial part of traceback was…

    Traceback (most recent call last):
    File “/usr/bin/pip”, line 33, in
    sys.exit(load_entry_point(‘pip==20.3.4’, ‘console_scripts’, ‘pip’)())
    File “/usr/bin/pip”, line 25, in importlib_load_entry_point
    return next(matches).load()
    File “/usr/lib/python3.9/importlib/metadata.py”, line 77, in load
    module = import_module(match.group(‘module’))
    File “/usr/lib/python3.9/importlib/__init__.py”, line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)

    Reply
    • Bob on 13. March 2023 1:21

      I tracked down part of the problem, installing Flask-Ask or something it brings along as a dependency locally or with sudo causes the error (at least on my machine). Manually deleting .local/flask* Flask*/ jinja*/ Jinja*/ crypto*/ six*/ restored my ability to do pip -V and pip list. Going to the Flask-Ask webpage and doing their install duplicates the problem on a fresh os installation.

      The following were not deleted:
      aniso8601==1.2.0
      pyOpenSSL==17.0.0
      PyYAML==5.4
      Werkzeug==0.16.1

      Reply

Leave A Reply Cancel Reply

Top 12 Advanced Robot Kits For Adults – Full Overview

Control Raspberry Pi Wireless Sockets (433MHz) – Tutorial

Creating a Raspberry Pi SSL Certificate For Free With Let’s Encrypt

Use Raspberry Pi as a Radio Receiver (FM Car Radio, Car PC)

Wireless communication between Raspberry Pi’s via MQTT broker/client

Raspberry Pi Bluetooth Data Transfer to the Smartphone

Subscribe to Blog
Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!
Subscribe

Thank you!

We will contact you soon.

Tutorials for Raspberry Pi
Facebook Twitter YouTube
  • Contact & Disclaimer

Type above and press Enter to search. Press Esc to cancel.