CONTENTS

Home
Updates
Software
Electronics
Android / iOS
Videos
Music
Resume
Contact



HTTPS VERSION


Alexa TV Remote Control

January 16, 2017

Introduction

I aquired an Amazon Echo Dot this year and decided I needed to learn how to write a skill for it. After making a test skill to get a feel for the API, I decided to try to make something useful. Since I tend to fall asleep with the TV on at night, I figured it would be useful to train Alexa to change TV channels or simply turn it off from the sound of my voice so I don't have to fumble around for the remote while I'm half alseep. I originally wanted to use a Bluetooth BLE device hooked up to an MSP430 circuit, but it seems Alexa doesn't currently have the ability to talk to random Bluetooth devices. Hopefully someone from Amazon reads this and adds the feature (or hires me to do it :). I ended up using an Electric Imp I had laying around from a previous project.

I wasn't so happy with the documentation on either Alexa or the Imp (especially the Squirrel language from the Imp) so I decided to write up what I did to make this work. Hopefully this helps someone else.

Related Projects @mikekohn.net

Infrared: Remote Control, IR Guitar Pickup, Sony SIRC Infrared,, R/C Propeller RPM, IR No Fly Zone, Syma Joystick, Paper ROM, Chromebook Remote, Remote Control Food, Alexa TV Remote

Video

Here is a video of me speaking to Alexa telling her to change channels and at the end turn the TV off. I tried to get a close up of the Electric Imp and the circuit board with the MSP430G2553 chip. https://youtu.be/CwNVapvE_lo

Explanation

Below I separated out the explanation into two parts, the Amazon Alexa side and the Electric Imp's side. Basically Alexa takes phrases spoken, turns them into JSON files and transfers them to the Imp's agent. The Imp's agent talks to the hardware device in my house which tells the MSP430 what command to spit out over IR to the TV. More on this below.

Alexa

The Alexa skill is mostly just a JSON file and some "utterances" that understand specific phrases. When Alexa sees a phrase she understands, she will create her own JSON file with information on what was said and POST it to the end-point URL provided, which in this case is the Electric Imp's agent page.

I separated out the Alexa part based on the tabs on the Amazon developer portal page. All of the Alexa programming below, defining utterances, intents, and endpoints is done in Amazon's cloud. No files are saved to the developer's own computer.

Skill Information

Every skill requires an invocation name. Under the skill information tab for my Television skill, I defined the invocation name as "television". This is how as a user I let Alexa know that I want to use this specific skill. I have to start my sentence with: Alexa tell television...

Pretty sure I can use any word after Alexa. Alexa ask television... etc.

Interaction Model Intents

The interaction model teaches Alexa which phrases to look for. In my case I want Alexa to know "Alexa tell television to turn on" or "Alexa tell television to turn to Fox The way this is done is through a group of "intents" an utterances. The utterances always start with a ... kind of function name. In my case I have two functions: DoPower and DoChannel. Both of these are defined in the intents JSON file.

For the DoChannel intent, it allows several channel names to be used. The list of channel names I allow to be spoken are in the LIST_OF_CHANNELS list that I define on this page. In the utterance I can use {channel} which tells Alexa that if she hears "turn to" and anything in that list, to match it as a valid phrase. There is an example of the JSON she will POST below in the "Test" section.

{
  "intents": [
    {
      "intent": "DoChannel",
      "slots": [
       {
        "name": "channel",
        "type": "LIST_OF_CHANNELS"
       }
      ]
    },
    {
      "intent": "DoPower",
      "slots": [
       {
        "name": "state",
        "type": "LIST_OF_STATES"
       }
      ]
    }
  ]
}

Interaction Model Custom Slot

LIST_OF_CHANNELS: Fox | Comet | C.W. | This | Me | My | Antenna | Justice | A.B.C. | N.B.C. | C.B.S

Interaction Model Utterances

  • DoChannel turn to {channel}
  • DoPower turn {state}

Configuration Endpoint

I used the HTTPS option (not the AWS Lamba stuff) and told it my endpoint was the agent address that the Electric Imp gave me for my "Television" model. It looks something like https://agent.electricimp.com/werwiuuierwu. Note that the endpoint must be secured socket https and not http. The endpoint can really be any webpage. My original first text Alexa skill pointed to a PHP page on my website.

SSL Certificate

There are three options here. For using Alexa with the Electric Imp agent page, I had to select the second one which reads "My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certified authority". When I made my first test skill that pointed to my website I was able to select the first option "My development endpoint has a certificate from a trust certificate authority". When I first tried to get the Alexa to talk to the Electric Imp agent, I had selected the first option and received no response on the Imp side. It was as if I gave a bad URL.

Test

Before actually speaking to the Amazon Echo Dot, I used the test feature. I could type: "tell television to turn to Fox" and Alexa would show me the exact JSON file it would send to the Electric Imp's agent and the response it got back from the Electric Imp. Very useful.

When I say "Alexa tell television to turn to Fox", she will send this to the Electric Imp's agent page:

{
  "session": {
    "sessionId": "",
    "application": {
      "applicationId": ""
    },
    "attributes": {},
    "user": {
      "userId": ""
    },
    "new": true
  },
  "request": {
    "type": "IntentRequest",
    "requestId": "",
    "locale": "en-US",
    "timestamp": "2017-01-16T15:37:49Z",
    "intent": {
      "name": "DoChannel",
      "slots": {
        "channel": {
          "name": "channel"
          "value": "fox"
        }
      }
    }
  },
  "version": "1.0"
}

The Electric Imp

So just like Alexa skills, the Electric Imp's programming environment is 100% cloud based. All code written is saved on the Electric Imp's servers. The Electric Imp's model is to expose a webpage to the outside world called an "agent". The agent runs code using the Squirrel language and can communicate to a piece of code that runs on the actual Electric Imp device. So the flow of data is this: I speak, Alexa realizes the skill and sends a JSON file to the Electric Imp's cloud server and runs my Television agent. That agent connects into my house to the Electric Imp hardware and tells the Electric Imp to change the channel. The Electric Imp tells an MSP430 microcontroller to send IR commands to the TV.

So again, the software to run the Imp is actually two programs both written in Squirrel. One to deal with web requests on the Imp's servers and one piece of code, again written in Squirrel, that runs on the actual hardware device.

Agent

function requestHandler(request, response)
{
  try
  { 
    local data = http.jsondecode(request.body);
    
    server.log(request.body);
    //server.log(data["request"]["intent"]["name"])

    local text = "I don't understand";    

    if ("request" in data)
    {
      if ("intent" in data["request"])
      {
        local intent = data["request"]["intent"];
        local name = intent["name"];
        
        //server.log("name is " + name);
        
        if (name == "DoChannel")
        {
          local value = intent["slots"]["channel"]["value"];
          
          device.send("pressRemote", value);
          text = "channel changed";
        }
        else if (name == "DoPower")
        {
          device.send("pressPower", 0);
          text = "power button pressed";
        }
      }
    }

    local json =
      "{" +
      "\"version\": \"1.0\"," +
      "\"response\": {" +
      "  \"outputSpeech\": {" +
      "  \"type\": \"PlainText\"," +
      "  \"text\": \"" + text + "\"" +
      "  }," +
      "\"shouldEndSession\": true" +
      "}" +
      "}"

    response.send(200, json);
  }
  catch (ex)
  {
    server.log("Error: " + ex);
    response.send(500, "Internal Server Error: " + ex);
  }
}

http.onrequest(requestHandler);

Device

local channels = {
  fox = "2",
  comet = "11-3",
  CW = "11",
  //this = "11-2",
  me = "4-2",
  my = "4-3",
  antenna = "2-2",
  justice = "5-3",
  ABC = "30",
  NBC = "5",
  CBS = "4",
}

channels["this"] <- "11-2";

function pressRemote(button)
{
  server.log("Button was " + button);
  hardware.pin1.write(0);

  if (button in channels)
  {
    uart.write(channels[button]);
  }
  else
  {
    server.log("Unknown button");
  }
}

function pressPower(button)
{
  hardware.pin1.write(1);
  uart.write(":");
}

// Debug LED
hardware.pin1.configure(DIGITAL_OUT);
hardware.pin1.write(1);

// If agent called "pressRemote", associate with
// the pressRemote function.
agent.on("pressRemote", pressRemote);
agent.on("pressPower", pressPower);

server.log(imp.environment() + " " + ENVIRONMENT_CARD);

// I know this is a version 1 IMP.
//serial = hardware.uart57;
uart <- hardware.uart57;
uart.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);

Pictures

Amazon Echo Dot with Electric Imp as a TV remote control.

On the right is the Amazon Echo Dot, in the middle is the MSP430G2553 circuit that controls the TV, and on the far right is the circuit with the Electric Imp.

Samsung TV remote schematic

Here is the schematic. It's the same circuit I used in the Chromebook Remote circuit.

Source code
chromebook_remote

Copyright 1997-2018 - Michael Kohn