Project tutorial
Alexa Smart Power Strip with Temperature

Alexa Smart Power Strip with Temperature © Apache-2.0

Smart Power Strip is controlled by Alexa Smart Home skills with an extra temperature feature. It can be used generally everywhere at home.

  • 1,269 views
  • 0 comments
  • 9 respects

Components and supplies

Abx00004 iso both
Arduino MKR1000
×1
10988 01
Temperature Sensor
×1
Generice 4 Channel Relay Module
×1
Amazon echo dot
Amazon Alexa Echo Dot
×1
Plastic Sheet 3MM Thick
×1

Necessary tools and machines

Lasercutter
Laser cutter (generic)

Apps and online services

About this project

When I heard about this contest, I thought many things. But an idea came to mind, we have many things in our home that we cannot control via Alexa/mobile phone like traditional fans, lights, TV, ovens, juicers, lightning strips and etc. So I planned to develop a generic smart power strip with temperature capability to control anything generically. And it's a portable power strip, you can move it to any room when you require. For example, you want to monitor the baby room temperature and control its fans, lights and heater. Or you want to monitor your parents room, then shift this gadget to their room, or if you want to wish a surprise to your loved one (I mean wife ;)), then move this smart power strip to your room and attach fancy lights strips and control all your traditional electronics with Alexa Smart Home skills. This Alexa-enabled power strip is also good for paralyzed persons (with voice) to control their basic appliances according to their mood - now, no more dependency on others! This power strip will also work like a thermostat.

Smart Home skill is great thing for developers. For this, we don't care about voice commands, we just need to focus on the device and its communication with Lambda. Alexa will handle all voice commands, send directives and requests to Lambda and then Lambda will generate the response after communication with the device cloud. You can more read about Alexa Smart Home skills: https://developer.amazon.com/alexa/smart-home

I am going to divide this project into the below 3 phases:

  • Preparation of Smart Power Strip
  • Connecting it to Cayenne Mydevices Cloud
  • Preparation of Smart Home Skill, Lambda to bridge Smart Home Skill with Cayenne MyDevices Cloud

Preparation of Smart Power Strip

First of all, collect all the above mentioned hardware components. And below is our very simple hardware assembling diagram which will demonstrate how the sensor and relay are connected with MKR1000.

Everything is simple except we have a single ground and I am not going to use any vero board. Take 3 female-to-female cables and join two cables head with the third cable, now we have 2 grounds. Connect one with TMP36 and the other with the relay.

  • Relay In1= Pin#1
  • Relay In2= Pin#2
  • Relay In3= Pin#3
  • Relay In4= Pin#4
  • Relay VCC=5V
  • TMP36 Data Pin= Pin#A1 (analog)

Connect its VCC to MKR1000 VCC (not with 5V because we are using TMP36 formula for 3.3V)

Note:* After completing the above step move to Cayenne Cloud Step for MKR1000 setup.

After completing the Cayenne Step we need to pack our stuff in a plastic box for protection or movement.

Connecting it to Cayenne Mydevices Cloud:

Cayenne MyDevices is a very nice IoT Cloud Platform which offers many features such as drag-n-drop of widgets by visual interface, triggers and etc. Please read this article for detailed Cayenne My Cloud Device Setup: click here.

After successful linkage, create 4 button widgets and 1 value widget for temperature. Assign the channel 1, 2, 3, 4 to button widgets as we assigned the relay pins to Arduino MKR1000.

After setting up the device and widgets at Cayenne, please update your below code with username, password and Client-ID and upload it to MKR1000. Test the product. If everything is working fine then again move back to the top for packing your hardware components in a box. If there is any problem, review everything carefully again or you can post the query in comments section. I will try my best to solve your problem.

Preparation of Smart Home Skill & AWS Lambda to bridge Smart Home Skill with Cayenne MyDevices Cloud:

Some important terminologies and short codes which will be used throughout the whole process.

  • LWA: login with Amazon
  • AWS: Amazon Web Service
  • Lambda: a service by Amazon to run any language code in a cloud without management of resources

Before we create the Smart Home skill we need to create LWA settings for the skill.

Open developer.amazon.com login and then click on Developer Console. Click on APP & Services, then on Login with Amazon and then click on Create a New Security Profile. Fill in the details. After that, you will receive Client ID and Client Secret; save these for future use.

Now click on Alexa and then click on Alexa Skills Kit.

Click on Add new Skill.

Select Smart Home Skill API. Enter your Skill Name.

When you click on the Save button, it will save the skill and generate the Application ID. Save it for AWS Lambda usage. Before we move to another step in Skill Development, we need to create a AWS Lambda for the skill so now it's time to move to https://console.aws.amazon.com/console/home.

Type Lambda in the search bar and select Lambda.

Click on Create Function.

Select Author from Scratch. Enter Function Name, and select Existing Role lambda_basic_execution. And click on Create Function.

After creating the function, you got ARN, save this for use in Skill Configuration. From the sidebar, drag Alexa Smart Home under your function.

After dragging, enter your Smart Home Skill Application ID and check on Trigger.

Now click on Function Name and you will see the Editor copy. And put the Lambda code below into Lambda Editor, but before saving please change your Cayenne Device ID & Sensor ID to work properly with them.

Now we need to move back to developer.amazon.com to complete other parts of the Alexa skill. Configuration is easy except the configuration tab. So we will focus on Alexa Configuration tab.

In Default, enter your AWS Lambda ARN & select the region. after that in Account Linking insert the ClientID and Client Secret that you can take from LWA. And in Authorization URL enter: https://www.amazon.com/ap/oa/, and Access Token URI: https://api.amazon.com/auth/o2/token. Under privacy policy, enter your privacy policy page URL.

After getting the all tabs green, you are able to test your application. Click on Manage Test and then you will begin testing the URL to install the skill.

Generic Electronic Appliance Demo:

Surprise Room Demo:

Future Work:

Due to time constraint, I was unable to include all features, but you can implement features like:

  • Turn on all the sockets by one command
  • Turn off the all sockets by one command
  • Automate your sockets with a temperature range like thermostat

Code

MKR1000 Smart power Strip Arduino CodeArduino
// This example shows how to connect to Cayenne using an Arduino/Genuino MKR1000 and send/receive sample data.

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTMKR1000.h>

// WiFi network info.
char ssid[] = "----SSID----";
char wifiPassword[] = "----SSID Password----";

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "----UserName-------";
char password[] = "----Password-------";
char clientID[] = "----Client ID-------";

unsigned long lastMillis = 0;

void setup() {
     Serial.begin(9600);
     pinMode(1,OUTPUT);
     pinMode(2,OUTPUT);
     pinMode(3,OUTPUT);
     pinMode(4,OUTPUT);
     pinMode(A1,INPUT);
 
	   Cayenne.begin(username, password, clientID, ssid, wifiPassword);
}

void loop() {
	  Cayenne.loop();

  	if (millis() - lastMillis > 100000) {
      float temperature=(((analogRead(A1)*3.22)-500)/10);
      Serial.print("Temperature=");
      Serial.println(temperature);
  		Cayenne.celsiusWrite(5, temperature);
  	}
}

CAYENNE_IN_DEFAULT()
{
  	CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
  	//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
    digitalWrite(request.channel,getValue.asInt());
}
AWS Lambda CodeJavaScript
This Lambda Code will bridge the Alexa Smart Home Skills API with Ceyenne Mydevices Cloud
exports.handler = function (request, context) {
	
	//Cayenne MyDevices DeviceID & SensorID 
	var Cayenne_DeviceID="-------Cayenne Device ID--------";
	var Cayenne_Temperature_SensorID="-------Cayenne Sensor ID--------";
	var Cayenne_UserName="---------Cayenne Account username-----------";
	var Cayenne_Password="---------Cayenne Account password-----------";
	
    if (request.directive.header.namespace === 'Alexa.Discovery' && request.directive.header.name === 'Discover') {
        log("DEBUG:", "Discover request",  JSON.stringify(request));
        handleDiscovery(request, context, "");
    }
    else if (request.directive.header.namespace === 'Alexa.PowerController') {
        if (request.directive.header.name === 'TurnOn' || request.directive.header.name === 'TurnOff') {
            log("DEBUG:", "TurnOn or TurnOff Request", JSON.stringify(request));
            handlePowerControl(request, context);
        }
    }else if(request.directive.endpoint.endpointId==="Appliance-001-05"){
		log("DEBUG:", "Temperature",  JSON.stringify(request));
		CayenneTemperatureControl(request,context);
	}
    function handleDiscovery(request, context) {
        var payload = {
            "endpoints":
            [
                {
                    "endpointId": "Appliance-001-01",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Socket One",
                    "description": "Smart Device Switch",
                    "displayCategories": ["SWITCH"],
                    "cookie": {
                    },
                    "capabilities":
                    [
                        {
                          "type": "AlexaInterface",
                          "interface": "Alexa",
                          "version": "3"
                        },
                        {
                            "interface": "Alexa.PowerController",
                            "version": "3",
                            "type": "AlexaInterface",
                            "properties": {
                                "supported": [{
                                    "name": "powerState"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                },{
                    "endpointId": "Appliance-001-02",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Socket Two",
                    "description": "Smart Device Switch",
                    "displayCategories": ["SWITCH"],
                    "cookie": {

                    },
                    "capabilities":
                    [
                        {
                          "type": "AlexaInterface",
                          "interface": "Alexa",
                          "version": "3"
                        },
                        {
                            "interface": "Alexa.PowerController",
                            "version": "3",
                            "type": "AlexaInterface",
                            "properties": {
                                "supported": [{
                                    "name": "powerState"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                },{
                    "endpointId": "Appliance-001-03",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Socket Three",
                    "description": "Smart Device Switch",
                    "displayCategories": ["SWITCH"],
                    "cookie": {
                    },
                    "capabilities":
                    [
                        {
                          "type": "AlexaInterface",
                          "interface": "Alexa",
                          "version": "3"
                        },
                        {
                            "interface": "Alexa.PowerController",
                            "version": "3",
                            "type": "AlexaInterface",
                            "properties": {
                                "supported": [{
                                    "name": "powerState"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                },{
                    "endpointId": "Appliance-001-04",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Socket Four",
                    "description": "Smart Device Switch",
                    "displayCategories": ["SWITCH"],
                    "cookie": {
                    },
                    "capabilities":
                    [
                        {
                          "type": "AlexaInterface",
                          "interface": "Alexa",
                          "version": "3"
                        },
                        {
                            "interface": "Alexa.PowerController",
                            "version": "3",
                            "type": "AlexaInterface",
                            "properties": {
                                "supported": [{
                                    "name": "powerState"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                },
				{
                    "endpointId": "Appliance-001-05",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Room Temperature",
                    "description": "Smart Room Temperature",
                    "displayCategories": ["THERMOSTAT"],
                    "cookie": {
                    },
                    "capabilities":
                    [
                        {
							"type": "AlexaInterface",
                            "interface": "Alexa.TemperatureSensor",
                            "version": "3",
                            "properties": {
                                "supported": [{
                                    "name": "temperature"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                }
			]
        };
        var header = request.directive.header;
        header.name = "Discover.Response";
        log("DEBUG", "Discovery Response: ", JSON.stringify({ header: header, payload: payload }));
        context.succeed({ event: { header: header, payload: payload } });
    }

    function log(message, message1, message2) {
        console.log(message + message1 + message2);
    }

    function handlePowerControl(request, context) {
        // get device ID passed in during discovery
        var requestMethod = request.directive.header.name;
        // get user token pass in request
        //var requestToken = request.directive.payload.scope.token;
        var powerResult;
		var CayenneDeviceChannel=request.directive.endpoint.endpointId.substr(request.directive.endpoint.endpointId.length-1,1);
        if (requestMethod === "TurnOn") {

            // Make the call to your device cloud for control 
            // powerResult = stubControlFunctionToYourCloud(endpointId, token, request);
            powerResult = "ON";
            CayennePowerControl(1,context,CayenneDeviceChannel);
        }
       else if (requestMethod === "TurnOff") {
            // Make the call to your device cloud for control and check for success 
            // powerResult = stubControlFunctionToYourCloud(endpointId, token, request);
            powerResult = "OFF";
			CayennePowerControl(0,context,CayenneDeviceChannel);
        }
		
    } 
  
	function TemperatureContext(request,context,value,Time_Stamp){
		var a = {
                         "context": {
                             "properties": [ {
                                "namespace": "Alexa.TemperatureSensor",
                                 "name": "temperature",
                                 "value": {
									"value": value,
									"scale": "CELSIUS"
								  },
                                 "timeOfSample": Time_Stamp,
                                 "uncertaintyInMilliseconds": 1000
                             }
                            ]
                         },
                        "event": {
                            "header": {
                                "namespace": "Alexa",
                                "name": "StateReport",
                                "payloadVersion": request.directive.header.payloadVersion,
                                "messageId": request.directive.header.messageId,
                                "correlationToken": request.directive.header.correlationToken
                            },
                            "endpoint": {
                                 "scope": {
                                 "type": "BearerToken",
                                 "token" :request.directive.endpoint.scope.token
                                 },
                                "endpointId": request.directive.endpoint.endpointId
                            },
                            "payload": {
                                "code":"LightIsOff",
                                "description":"Light is off.",
                                "message":"Light is off"
                            }
                        }
                    };
					log("DEBUG:", "StateReport",  JSON.stringify(a));
					context.succeed(a);
	}
	function PowerContext(context){
		var a = {
                         "context": {
                             "properties": [ {
                                "namespace": "Alexa.PowerController",
                                 "name": "powerState",
                                 "value": "ON",
                                 "timeOfSample": "2017-02-03T16:20:50.52Z",
                                 "uncertaintyInMilliseconds": 5000
                             },{
                                "namespace": "Alexa.EndpointHealth",
                                "name": "connectivity",
                                "value": {
                                    "value": "OK Good"
                                },
                                "timeOfSample": "2017-09-27T18:30:30.45Z",
                                "uncertaintyInMilliseconds": 200
                                }
                            ]
                         },
                        "event": {
                            "header": {
                                "namespace": "Alexa",
                                "name": "Response",
                                "payloadVersion": request.directive.header.payloadVersion,
                                "messageId": request.directive.header.messageId,
                                "correlationToken": request.directive.header.correlationToken
                            },
                            "endpoint": {
                                 "scope": {
                                 "type": "BearerToken",
                                 "token" :request.directive.endpoint.scope.token
                                 },
                                "endpointId": request.directive.endpoint.endpointId
                            },
                            "payload": {
                                "code":"LightIsOff",
                                "description":"Light is off.",
                                "message":"Light is off"
                            }
                        }
                    };
					
					context.succeed(a);
	}
    function CayennePowerControl(turn,context,CayenneDeviceChannel){
        var http = require('https');
		var AccessToken="";
		var body = JSON.stringify({
			"grant_type": "password",
			"email":Cayenne_UserName,
			"password":Cayenne_Password
		});

		var options={
			hostname: "auth.mydevices.com",
			path: "/oauth/token",
			method: "POST",
			headers: {
				"Content-Type": "application/json",
				"Content-Length": Buffer.byteLength(body)
			}
		};
		var req=http.request(options,function(res){
			var responseString = "";

			res.on("data", function (data) {
				responseString += data;
				// save all the data from response
			});
			res.on("end", function () {
				var jsonRes=JSON.parse(responseString);
				AccessToken=jsonRes['access_token'];
				console.log("DEBUG:"+AccessToken);
				
				
				//Write the Values
				if(AccessToken!=""){
					var cmdValue = JSON.stringify({
						"value":turn,
						"channel": CayenneDeviceChannel
					});
					var options1={
					hostname: "platform.mydevices.com",
					path: "/v1.1/things/"+Cayenne_DeviceID+"/cmd",
					method: "POST",
						headers: {
							"Authorization": "Bearer "+AccessToken,
							"Content-Type": "application/json; charset=UTF-8",
							"Content-Length": Buffer.byteLength(cmdValue)
						}
					};
					var req1=http.request(options1,function(res1){
						var Result = "";

						res1.on("data", function (data) {
							Result += data;
							
							// save all the data from response
						});
						res1.on("end", function () {
							console.log("DEBUG:"+Result);
							PowerContext(context);
						});
					}).write(cmdValue);
				}
				
				
			});
		}).write(body);

         
    }

	 function CayenneTemperatureControl(request,context){
        var http = require('https');
		var AccessToken="";
		var body = JSON.stringify({
			"grant_type": "password",
			"email":Cayenne_UserName,
			"password":Cayenne_Password
		});

		var options={
			hostname: "auth.mydevices.com",
			path: "/oauth/token",
			method: "POST",
			headers: {
				"Content-Type": "application/json",
				"Content-Length": Buffer.byteLength(body)
			}
		};
		var req=http.request(options,function(res){
			var responseString = "";

			res.on("data", function (data) {
				responseString += data;
				// save all the data from response
			});
			res.on("end", function () {
				var jsonRes=JSON.parse(responseString);
				AccessToken=jsonRes['access_token'];
				console.log("DEBUG:"+AccessToken);
				
				
				//Write the Values
				if(AccessToken!=""){
					var options1={
						hostname: "platform.mydevices.com",
						path: "/v1.1/telemetry/"+Cayenne_DeviceID+"/sensors/"+Cayenne_Temperature_SensorID+"/summaries?type=latest",
						method: "GET",
							headers: {
								"Authorization": "Bearer "+AccessToken,
							}
						};
						var req1=http.request(options1,function(res1){
							var Result = "";

							res1.on("data", function (data) {
								Result += data;
								// save all the data from response
							});
							res1.on("end", function () {
								console.log(Result);
								Result=JSON.parse(Result);
								var Temperature_Value=Result[0].v;
								var Time_Stamp=Result[0].ts;
								TemperatureContext(request,context,Temperature_Value,Time_Stamp);
							});
						}).end();
				}
				
				
			});
		}).write(body);

         
    }
	
};

Schematics

Fritzing circult diagram.
mkr1000-smart-power-strip_xs5txq9OTG.fzz

Comments

Similar projects you might like

Hygge Home - Alexa Smart Bath

Project tutorial by J Howard

  • 5,365 views
  • 2 comments
  • 18 respects

BOFF - Alexa Enabled Open Smart Fan

Project showcase by Stephen Harrison

  • 7,800 views
  • 6 comments
  • 28 respects

Alexa Enabled USB Power Switch

Project tutorial by Stephen Harrison

  • 3,734 views
  • 7 comments
  • 30 respects

Smart Pool: Alexa Controlled Pool Manager

Project tutorial by Benjamin Winiarski

  • 1,370 views
  • 2 comments
  • 7 respects

Animated Smart Light with Alexa and Arduino

Project tutorial by Bruno Portaluri

  • 4,231 views
  • 9 comments
  • 25 respects

Smart Garden - Alexa consults & automates your garden

Project in progress by Alex Winiarski

  • 826 views
  • 2 comments
  • 4 respects
Add projectSign up / Login