phpoc_man
Published © GPL3+

Amazon Echo - LED Strip

This project allows you to use voice command to turn on/off, change color, effect of one, a range or all of an LED strip.

AdvancedFull instructions provided3,268
Amazon Echo -  LED Strip

Things used in this project

Hardware components

Echo Dot
Amazon Alexa Echo Dot
×1
PHPoC Blue
PHPoC Blue
×1
PHPoC 4-Port Relay Expansion Board (S-type or T-type)
PHPoC 4-Port Relay Expansion Board (S-type or T-type)
×14
Adafruit RGB LED Strip
×9

Software apps and online services

Alexa Skills Kit
Amazon Alexa Alexa Skills Kit
AWS Lambda
Amazon Web Services AWS Lambda
MQTT
MQTT

Story

Read more

Schematics

Hardware

Code

Lambda function (index.js)

JavaScript
/**
 * This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit.
 * The Intent Schema, Custom Slots, and Sample Utterances for this skill, as well as
 * testing instructions are located at http://amzn.to/1LzFrj6
 *
 * For additional samples, visit the Alexa Skills Kit Getting Started guide at
 * http://amzn.to/1LGWsLG
 */

var mqtt = require('mqtt');

// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = function (event, context) {
	try {
		console.log("event.session.application.applicationId=" + event.session.application.applicationId);

		/**
		 * Uncomment this if statement and populate with your skill's application ID to
		 * prevent someone else from configuring a skill that sends requests to this function.
		 */
		/*
		if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.[unique-value-here]") {
			 context.fail("Invalid Application ID");
		}
		*/

		if (event.session.new) {
			onSessionStarted({requestId: event.request.requestId}, event.session);
		}

		if (event.request.type === "LaunchRequest") {
			onLaunch(event.request,
				event.session,
				function callback(sessionAttributes, speechletResponse) {
					context.succeed(buildResponse(sessionAttributes, speechletResponse));
				});
		} else if (event.request.type === "IntentRequest") {
			onIntent(event.request,
				event.session,
				function callback(sessionAttributes, speechletResponse) {
					context.succeed(buildResponse(sessionAttributes, speechletResponse));
				});
		} else if (event.request.type === "SessionEndedRequest") {
			onSessionEnded(event.request, event.session);
			context.succeed();
		}
	} catch (e) {
		context.fail("Exception: " + e);
	}
};

/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
	console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId +
		", sessionId=" + session.sessionId);
}

/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
	console.log("onLaunch requestId=" + launchRequest.requestId +
		", sessionId=" + session.sessionId);

	// Dispatch to your skill's launch.
	getWelcomeResponse(callback);
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
	console.log("onIntent requestId=" + intentRequest.requestId +
		", sessionId=" + session.sessionId);

	var intent = intentRequest.intent,
		intentName = intentRequest.intent.name;

	// Dispatch to your skill's intent handlers
	if ("LedStrip" === intentName) {
		setLightInSession(intent, session, callback);
	} else if ("AMAZON.HelpIntent" === intentName) {
		getWelcomeResponse(callback);
	} else if ("AMAZON.StopIntent" === intentName || "AMAZON.CancelIntent" === intentName) {
		handleSessionEndRequest(callback);
	} else {
		throw "Invalid intent";
	}
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
	console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId + ", sessionId=" + session.sessionId);
	// Add cleanup logic here
}

// --------------- Functions that control the skill's behavior -----------------------

function getWelcomeResponse(callback) {
	// If we wanted to initialize the session to have some attributes we could add those here.
	var sessionAttributes = {};
	var cardTitle = "Welcome";
	var speechOutput = "Welcome to P H P o C. How can I help you?";
	
	// If the user either does not reply to the welcome message or says something that is not
	// understood, they will be prompted again with this text.
	var repromptText = "How can I help you?";
	var shouldEndSession = false;
	
	callback(sessionAttributes,
		buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}

function handleSessionEndRequest(callback) {
	var cardTitle = "Session Ended";
	var speechOutput = "Thank you for trying the P h p o c  example. Have a nice day!";
	// Setting this to true ends the session and exits the skill.
	var shouldEndSession = true;
	
	callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}

/**
 * Sets the led in the session and prepares the speech to reply to the user.
 */
function setLightInSession(intent, session, callback) {
	var cardTitle = intent.name;
	
	var colorStateRequest = intent.slots.ColorState;
	var ledFromRequest = intent.slots.FromLed;
	var ledToRequest = intent.slots.ToLed;
	var ledStateRequest = intent.slots.LedState;
	var effectRequest = intent.slots.Effect;

	var repromptText = "";
	var sessionAttributes = {};
	var shouldEndSession = true;
	var speechOutput = "";
	
	if(colorStateRequest || ledFromRequest || ledToRequest || ledStateRequest || effectRequest)
	{
		var colorState = colorStateRequest.value;
		var ledFrom = ledFromRequest.value;
		var ledTo = ledToRequest.value;
		var ledState = ledStateRequest.value;
		var effect = effectRequest.value;
		
		if (colorState === undefined) 
			colorState = "";
		
		if (ledFrom === undefined) 
			ledFrom = 0;
		
		if (ledTo === undefined) 
			ledTo = 0;
		
		if (ledState === undefined) 
			ledState = "";
		
		if (effect === undefined) 
			effect = "";
		
		var responseAlexa = "";
		
		if(colorState != "")
		{
			responseAlexa = "Ok, changing color of led strip ";
			
			if(ledFrom != 0 && ledTo !=0)
				responseAlexa += "from number " + ledFrom + " to number " + ledTo + " to " + colorState;
			else if(ledFrom != 0)
				responseAlexa += "number " + ledFrom + " to " + colorState;
			else
				responseAlexa += " to " +  colorState;
		}
		else if(ledState != "")
		{
			responseAlexa = "Ok, turning ";
			if(ledFrom != 0 && ledTo !=0)
				responseAlexa += ledState + " led strip from number " + ledFrom + " to number " + ledTo;
			else if(ledFrom != 0)
			{
				if(ledFrom == "all")
					responseAlexa += ledState + " all led strip";
				else
					responseAlexa += ledState + " led strip number " + ledFrom;
			}
		}
		else if(effect != "")
		{
			responseAlexa = "Ok, change effect of led ";
			
			if(ledFrom != 0 && ledTo !=0)
				responseAlexa += "from number " + ledFrom + " to number " + ledTo + " to " + effect;
			else if(ledFrom != 0)
				responseAlexa += "number " + ledFrom + " to " + effect;
			else
				responseAlexa = "Ok, change effect to " + effect;
		}
		else
		{
			responseAlexa = "Please try again";
		}
		
		if (ledFrom === "all") 
			ledFrom = 15;
		
		var paramsUpdate = ' {"color" : "' + colorState + '", "from" : ' + ledFrom + ', "to" : ' + ledTo + ', "state" : "' + ledState + '", "effect" : "' + effect + '"}';
		
		//Update 
		var mqttpromise = new Promise( function(resolve,reject){
			var client = mqtt.connect({port:1883,host:'iot.eclipse.org'})
			
			client.on('connect', function() { // When connected
				// publish a message to a topic
				client.publish('phpoc/alexa/ledstrip', paramsUpdate)
				client.end()
				resolve('Done Sending');
			});
			
		});
		mqttpromise.then(
			function(data) {
				console.log('Function called succesfully:', data);
				sessionAttributes = createcolorStateAttributes(colorState);
				speechOutput = responseAlexa;
				repromptText = responseAlexa;
				callback(sessionAttributes,buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
			},
			function(err) {
				console.log('An error occurred:', err);
			}
		);
		 
	} else {
		speechOutput = "Please try again";
		repromptText = "Please try again";
		callback(sessionAttributes,buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
	}
}

function createcolorStateAttributes(colorState) {
	return {
		colorState: colorState
	};
}

// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
	return {
		outputSpeech: {
			type: "PlainText",
			text: output
		},
		card: {
			type: "Simple",
			title: "SessionSpeechlet - " + title,
			content: "SessionSpeechlet - " + output
		},
		reprompt: {
			outputSpeech: {
				type: "PlainText",
				text: repromptText
			}
		},
		shouldEndSession: shouldEndSession
	};
}

function buildResponse(sessionAttributes, speechletResponse) {
	return {
		version: "1.0",
		sessionAttributes: sessionAttributes,
		response: speechletResponse
	};
}

PHPoC Source Code (task0.php)

PHP
<?php

if(_SERVER("REQUEST_METHOD"))
    exit; // avoid php execution via http request

include_once "/lib/sd_spc.php";
include_once "/lib/sn_dns.php";
include_once "/lib/sn_json.php";
include_once "/lib/vn_mqtt.php";

define("RED",		1);
define("GREEN",		2);
define("BLUE",		4);
define("YELLOW",	RED | GREEN);
define("CYAN",		GREEN | BLUE);
define("MAGENTA",	RED | BLUE);
define("WHITE",		RED | GREEN | BLUE);

define("EFFECT_NORMAL",		1);
define("EFFECT_BLINK",		2);
define("EFFECT_COLOR",		3);
define("EFFECT_DOMINO",		4);

define("ON",		1);
define("OFF",		0);

function led_strip_get_tick()
{
	while(($pid = pid_open("/mmap/st0", O_NODIE)) == -EBUSY)
		usleep(500);

	if(!pid_ioctl($pid, "get state"))
		pid_ioctl($pid, "start");

	$tick = pid_ioctl($pid, "get count");
	pid_close($pid);

	return $tick;
}
function get_color_code($color_name)
{
	$color_name = strtoupper($color_name);
	
	if($color_name == "RED")
		return RED;
	if($color_name == "GREEN")
		return GREEN;
	if($color_name == "BLUE")
		return BLUE;
	if($color_name == "YELLOW")
		return YELLOW;
	if($color_name == "CYAN")
		return CYAN;
	if($color_name == "MAGENTA")
		return MAGENTA;
	if($color_name == "WHITE")
		return WHITE;

	return 0;
}

spc_reset();
spc_sync_baud(115200);

//$host_name = "test.mosquitto.org";
$host_name = "iot.eclipse.org";
//$host_name = "broker.hivemq.com";
//$host_name = "broker.mqttdashboard.com";
//$host_name = "[112.171.138.90]";
$port = 1883;

mqtt_setup(0, "PHPoC-MQTT Sub Example",  $host_name, $port); 

$will = "";
$username = "";
$password = "";

mqtt_connect(true, $will, $username, $password);

$out_topics = array(array("phpoc/alexa/ledstrip", 0));

if(mqtt_state() == MQTT_CONNECTED)
    mqtt_subscribe($out_topics);

$in_topic = "";
$in_content = "";
$is_retain = 0;

$led_from = 0;
$led_to = 0;
$led_effect = array("normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal", "normal");
$led_color = array(WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE);
$led_state = array(OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF);

$update = true;

while(1)
{
	if(mqtt_state() == MQTT_DISCONNECTED)
		while(mqtt_reconnect() == false);
	
	if(mqtt_loop($in_topic, $in_content, $is_retain))
	{
		//TODO , procees the received publish packet here
		if($is_retain == 1)
			echo "<<a stale message\r\n";
		
		echo "<<topic:$in_topic\r\n";
		echo "<<content: $in_content\r\n";
		
		$color	= json_text_value(json_search($in_content, "color"));
		$from	= (int)json_search($in_content, "from");
		$to		= (int)json_search($in_content, "to");
		$state	= json_text_value(json_search($in_content, "state"));
		$effect = json_text_value(json_search($in_content, "effect"));
		
		if($from > 15 || $to > 15)
			continue;
		
		if($from == 15)
		{
			$led_from = 1;
			$led_to = 14;
		}
		else if($from != 0)
		{
			$led_from = $from;
			$led_to = $to;
		}
		
		if($color != "")
		{
			$color_value = get_color_code($color);
			
			if($from != 0 && $to == 0)
				$led_color[$from - 1] = $color_value;
			else if($from != 0 && $to != 0)
			{
				for($i = $led_from; $i <= $led_to; $i++)
				{
					$led_color[$i - 1] = $color_value;
				}
			}
			else if($from == 0 && $to == 0)
			{
				for($i = 1; $i <= 14; $i++)
				{
					$led_color[$i - 1] = $color_value;
				}
			}
		}
		
		if($state != "" && $led_from != 0)
		{
			$state_value = ($state == "on") ? ON : OFF;
			
			if($led_to == 0)
			{
				$led_state[$led_from - 1] = $state_value;
				$led_effect[$led_from - 1] = "normal";
			}
			else
			{
				for($i = $led_from; $i <= $led_to; $i++)
				{
					$led_state[$i - 1] = $state_value;
					$led_effect[$i - 1] = "normal";
				}
			}
		}
		
		if($effect != "")
		{
			if($from != 0 && $to == 0)
			{
				$led_effect[$from - 1] = $effect;
				if($effect != "normal")
					$led_state[$from - 1] = ON;
			}
			else if($from != 0 && $to != 0)
			{
				for($i = $led_from; $i <= $led_to; $i++)
				{
					$led_effect[$i - 1] = $effect;
					if($effect != "normal")
						$led_state[$i - 1] = ON;
				}
			}
			else if($from == 0 && $to == 0)
			{
				for($i = 1; $i <= 14; $i++)
				{
					$led_effect[$i - 1] = $effect;
					if($effect != "normal")
						$led_state[$i - 1] = ON;
				}
			}
		}
		
		$update = true;
	}
	$curr_time = led_strip_get_tick();
	
	for($i = 0; $i < 14; $i++)
	{
		$effect = $led_effect[$i];
		switch($effect)
		{
			case "normal":
				//$update = true;
				break;
			case "blink":
				if(($curr_time - $update_time) > 1500)
				{
					//if($led_state[$i] == ON)
						$led_state[$i] = ($led_state[$i] + 1) % 2;
					
					$update = true;
				}
				break;
			case "color":
				if(($curr_time - $update_time) > 1500)
				{
					$led_color[$i] = ($led_color[$i] + 1) % 8;
					
					$update = true;
				}
				break;
			case "domino":
				
				break;
		}
	}
	
	if($update)
	{
		for($i = 1; $i <= 14; $i++)
		{
			if($led_state[$i - 1] == OFF)
			{
				spc_request($i, 4, "set 0 output low"); usleep(10);
				spc_request($i, 4, "set 1 output low"); usleep(10);
				spc_request($i, 4, "set 2 output low"); usleep(10);
			}
			else
			{
				$color = $led_color[$i - 1];
				
				$state = ($color & RED) ? "high" : "low";
				spc_request($i, 4, "set 0 output $state"); usleep(10);
				$state = ($color & GREEN) ? "high" : "low";
				spc_request($i, 4, "set 1 output $state"); usleep(10);
				$state = ($color & BLUE) ? "high" : "low";
				spc_request($i, 4, "set 2 output $state"); usleep(10);
			}
		}
		
		$update_time = led_strip_get_tick();
		$update = false;
	}
}
//mqtt_unsubscribe("sensors/temperature");
    
mqtt_disconnect();

?>

Credits

phpoc_man

phpoc_man

5 projects • 399 followers

Comments

Add projectSign up / Login