Moritz Strube
Published © Apache-2.0

Switch TV On and Off with Alexa and Photon

Talking to Alexa will trigger a Particle.io API call which will trigger a IR LED to send control codes to your TV.

IntermediateFull instructions provided2 hours2,718
Switch TV On and Off with Alexa and Photon

Things used in this project

Hardware components

Amazon Echo
Amazon Alexa Amazon Echo
×1
Photon
Particle Photon
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
Resistor 100 ohm
Resistor 100 ohm
×1
Resistor 1k ohm
Resistor 1k ohm
×1
LED Infrared 950nm
×1
IR receiver (generic)
Optional
×1

Software apps and online services

AWS Lambda
Amazon Web Services AWS Lambda
Particle.io
Alexa Skills Kit
Amazon Alexa Alexa Skills Kit

Story

Read more

Schematics

Schematics

Code

Photon Code

C/C++
int sendIR(String s);
int IRledPin = A4;
int led = D7;

void setup() {
    pinMode(IRledPin, OUTPUT);
    pinMode(led, OUTPUT);
    Serial.begin(9600);
    Particle.function("send", sendIR);
}

void loop() {
}

void pulse(long microsecs) {
    while (microsecs > 0) {
        // 38 kHz is about 13 microseconds high and 13 microseconds low
        digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen
        delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working
        digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds
        delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working
        // so 26 microseconds altogether
        microsecs -= 26;
    }
}

int sendIR(String s) {
    
    // visual confirmation
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
    
    pulse(5000);
    delayMicroseconds(5000);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(560);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    delayMicroseconds(1600);
    pulse(560);
    
    return 1;
}

Alexa Intent Schema

JSON
The intent schema has to be pasted in the intent schema box in the Interaction model section of the Alexa skill in the Alexa Skills Kit Ui.
{
  "intents": [
    {
      "intent": "SwitchOnIntent"
    },
    {
      "intent": "SwitchOffIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}

Sample utterances

snippets
The sample utterances have to be pasted in the sample utterances box in the Interaction model section of the Alexa skill in the Alexa Skills Kit Ui.
SwitchOnIntent switch t v on
SwitchOnIntent switch television on
SwitchOnIntent switch t v set on
SwitchOnIntent on
SwitchOffIntent switch t v off
SwitchOffIntent switch television off
SwitchOffIntent switch t v set off
SwitchOffIntent off

AWS Lambda Code

JavaScript
Node.js code for a AWS Lambda Function for Alexa. Save it as index.js.
'use strict';
const Alexa = require('alexa-sdk');
const p = require('./particle.js');

const languageString = {
    "en-US": {
        "translation": {
            "WELCOME_MESSAGE": "t v remote is ready. ",
            "STOP_MESSAGE": "Stopped. ",
            "ON_MESSAGE": "I switch the t v on for you. ",
            "OFF_MESSAGE": "I switch the t v off for you. ",
            "HELP_MESSAGE": "Say: Switch on the t v or switch off the t v. ",
            "HELP_REPROMPT": "Say: Switch on the t v or switch off the t v. ",
            "ERROR_MESSAGE": "Something went wrong. "
        }
    },
     "en-GB": {
        "translation": {
            "WELCOME_MESSAGE": "t v remote is ready. ",
            "STOP_MESSAGE": "Stopped. ",
            "ON_MESSAGE": "I switch the t v on for you. ",
            "OFF_MESSAGE": "I switch the t v off for you. ",
            "HELP_MESSAGE": "Say: Switch on the t v or switch off the t v. ",
            "HELP_REPROMPT": "Say: Switch on the t v or switch off the t v. ",
            "ERROR_MESSAGE": "Something went wrong. "
        }
    },
    "de-DE": {
        "translation": {
            "WELCOME_MESSAGE": "Fernbedienung ist gestartet. ",
            "STOP_MESSAGE": "Beendet. ",
            "ON_MESSAGE": "Ich schalte den Fernseher für dich an. ",
            "OFF_MESSAGE": "Ich schalte den Fernseher für dich aus. ",
            "HELP_MESSAGE": "Sage: Schalte Fernseher an oder Schalte Fernseher aus. ",
            "HELP_REPROMPT": "Sage: Schalte Fernseher an oder Schalte Fernseher aus. ",
            "ERROR_MESSAGE": "Das hat leider nicht funktioniert. "
        }
    }
};

const password = process.env.PASSWORD;
const username = process.env.USERNAME;
const deviceid = process.env.DEVICEID;
const appid    = process.env.APPID;

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.appId = appid;  
    alexa.resources = languageString;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

const handlers = {
    'LaunchRequest': function () {
        const self = this; 
        p.particle_get_token(username,password).then(  
            access_token => {
                self.attributes["token"] = access_token;
                const speechOutput = self.t('WELCOME_MESSAGE');
                self.emit(':ask',speechOutput);
      
            },
            err => {
                console.log(`Fehler: ${err}`);
            }
        );
    },
    'SwitchOnIntent': function () {
        // function send is implemented in sendrawir.ino
        this.emit('Call','send',this.t('ON_MESSAGE')); 
    }      
    ,
    'SwitchOffIntent': function () {
        // function send is implemented in sendrawir.ino
        this.emit('Call','send',this.t('OFF_MESSAGE'));     
    },
    'Call': function(func,message) {
        const self = this; 
        if(this.attributes["token"]) {
            let access_token=this.attributes["token"];
            p.particle_function_call(access_token,deviceid,func).then( 
                body => {
                    const speechOutput = message; 
                    self.emit(':tell', speechOutput); 
                },
                err => {
                    console.log(`${err}`);
                    const speechOutput = this.t('ERROR_MESSAGE');
                    self.emit(':tell',speechOutput);
                }
            );
        }
        else {
           const speechOutput = this.t('ERROR_MESSAGE');
           self.emit(':tell',speechOutput); 
           // TODO: end here
        }

    },
    'AMAZON.HelpIntent': function () {
        const speechOutput = this.t('HELP_MESSAGE');
        const reprompt = this.t('HELP_MESSAGE');
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
    'SessionEndedRequest': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    }
};

AWS Lambda Code for Particle Photon

JavaScript
Node.js code for a AWS Lambda Function for Particle Photon. Save it as particle.js.
const rp = require('request-promise');
const request = require('request');

exports.particle_get_token = (username,password) => {
	
	const options = {

		method: 'POST',
		uri: 'https://api.particle.io/oauth/token',
		auth: {
			user: 'particle',
			pass: 'particle'
		},
		headers: {
			contentType: 'application/x-www-form-urlencoded',
		},
		form: {
			grant_type: 'password',
	    	username: username,
	    	password: password
		}
	}
	
	return rp(options).then(
		body => {
			const access_token = JSON.parse(body).access_token;
			return(access_token);
		},
		err => {
			console.log(`${err}`);
			return(err);
		}
	);
}

exports.particle_function_call = (access_token,deviceid,api_function) => {

	const options = {
	
		method: 'POST',
		uri: `https://api.particle.io/v1/devices/${deviceid}/${api_function}`,
		headers: {
			contentType: 'application/x-www-form-urlencoded',
		},
		form: {
			access_token: access_token,
		}
	}

	return rp(options).then(
		body => {
			return(body);
		}, 
		err => {
			console.log(`${err}`);
			return(err);
		}
	);
};
   

Credits

Moritz Strube

Moritz Strube

4 projects • 7 followers
I’m an experienced technology manager with deep interest in technology, innovation and science.

Comments