Skip to content

Instantly share code, notes, and snippets.

@TheSkorm
Created November 28, 2015 09:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheSkorm/9569d3796081308eeccb to your computer and use it in GitHub Desktop.
Save TheSkorm/9569d3796081308eeccb to your computer and use it in GitHub Desktop.
/**
* This sample demonstrates a simple driver built against the Alexa Lighting Api.
* For additional details, please refer to the Alexa Lighting API developer documentation
* https://developer.amazon.com/public/binaries/content/assets/html/alexa-lighting-api.html
*/
var https = require('https');
var REMOTE_CLOUD_BASE_PATH = '/';
var REMOTE_CLOUD_HOSTNAME = 'www.amazon.com';
var https = require('https');
/**
* Main entry point.
* Incoming events from Alexa Lighting APIs are processed via this method.
*/
exports.handler = function(event, context) {
log('Input', event);
switch (event.header.namespace) {
/**
* The namespace of "Discovery" indicates a request is being made to the lambda for
* discovering all appliances associated with the customer's appliance cloud account.
* can use the accessToken that is made available as part of the payload to determine
* the customer.
*/
case 'Discovery':
handleDiscovery(event, context);
break;
case 'System':
handleHealthCheck(event, context);
break;
/**
* The namespace of "Control" indicates a request is being made to us to turn a
* given device on, off or brighten. This message comes with the "appliance"
* parameter which indicates the appliance that needs to be acted on.
*/
case 'Control':
handleControl(event, context);
break;
/**
* We received an unexpected message
*/
default:
log('Err', 'No supported namespace: ' + event.header.namespace);
context.fail('Something went wrong');
break;
}
};
function handleHealthCheck(event, context){
healthcheck = {
"header": {
"namespace": "System",
"name": "HealthCheckResponse",
"payloadVersion": "1"
},
"payload": {
"isHealthy": true,
"description": "The system is currently healthy"
}
}
context.succeed(healthcheck);
}
/**
* This method is invoked when we receive a "Discovery" message from Alexa Connected Home Skill.
* We are expected to respond back with a list of appliances that we have discovered for a given
* customer.
*/
function handleDiscovery(accessToken, context) {
/**
* Crafting the response header
*/
var headers = {
namespace: 'Discovery',
name: 'DiscoverAppliancesResponse',
payloadVersion: '1'
};
var options={
auth: "username",
hostname: "hostname",
method: "GET",
path: "/api/devices",
port: 443,
}
appliances = []
https.get(options, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
var response = JSON.parse(body);
var length = response.devices.length
for(x = 0; x<length; x++)
{
console.log(response.devices[x])
var device = {
"manufacturerName": "pimatic",
"modelName": "pimatic",
"version": "1",
"isReachable": true,
"additionalApplianceDetails": {}
}
device["applianceId"] = response.devices[x].id
device["friendlyName"] = response.devices[x].name
device["friendlyDescription"] = response.devices[x].name
appliances.push(device)
}
/**
* Craft the final response back to Alexa Connected Home Skill. This will include all the
* discoverd appliances.
*/
var payloads = {
discoveredAppliances: appliances
};
var result = {
header: headers,
payload: payloads
};
log('Discovery', result);
context.succeed(result);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
}
/**
* Control events are processed here.
* This is called when Alexa requests an action (IE turn off appliance).
*/
function handleControl(event, context) {
/**
* Fail the invocation if the header is unexpected. This example only demonstrates
* turn on / turn off, hence we are filtering on anything that is not SwitchOnOffRequest.
*/
if (event.header.namespace != 'Control' || event.header.name != 'SwitchOnOffRequest') {
context.fail(generateControlError('SwitchOnOffRequest', 'UNSUPPORTED_OPERATION', 'Unrecognized operation'));
}
if (event.header.namespace === 'Control' && event.header.name === 'SwitchOnOffRequest') {
/**
* Retrieve the appliance id and accessToken from the incoming message.
*/
var applianceId = event.payload.appliance.applianceId;
var accessToken = event.payload.accessToken.trim();
log('applianceId', applianceId);
/**
* Make a remote call to execute the action based on accessToken and the applianceId and the switchControlAction
* Some other examples of checks:
* validate the appliance is actually reachable else return TARGET_OFFLINE error
* validate the authentication has not expired else return EXPIRED_ACCESS_TOKEN error
* Please see the technical documentation for detailed list of errors
*/
var basePath = '';
if (event.payload.switchControlAction === 'TURN_ON') {
basePath = '/api/device/' + applianceId + '/turnOn';
} else if (event.payload.switchControlAction === 'TURN_OFF') {
basePath = '/api/device/' + applianceId + '/turnOff';
}
var options={
auth: "username:passowrd",
hostname: "hostname",
method: "GET",
path: basePath,
port: 443,
}
var serverError = function (e) {
log('Error', e.message);
/**
* Craft an error response back to Alexa Connected Home Skill
*/
context.fail(generateControlError('SwitchOnOffRequest', 'DEPENDENT_SERVICE_UNAVAILABLE', 'Unable to connect to server'));
};
var callback = function(response) {
var str = '';
response.on('data', function(chunk) {
str += chunk.toString('utf-8');
});
response.on('end', function() {
/**
* Test the response from remote endpoint (not shown) and craft a response message
* back to Alexa Connected Home Skill
*/
log('done with result');
var headers = {
namespace: 'Control',
name: 'SwitchOnOffResponse',
payloadVersion: '1'
};
var payloads = {
success: true
};
var result = {
header: headers,
payload: payloads
};
log('Done with result', result);
context.succeed(result);
});
response.on('error', serverError);
};
/**
* Make an HTTPS call to remote endpoint.
*/
https.get(options, callback)
.on('error', serverError).end();
}
}
/**
* Utility functions.
*/
function log(title, msg) {
console.log('*************** ' + title + ' *************');
console.log(msg);
console.log('*************** ' + title + ' End*************');
}
function generateControlError(name, code, description) {
var headers = {
namespace: 'Control',
name: name,
payloadVersion: '1'
};
var payload = {
exception: {
code: code,
description: description
}
};
var result = {
header: headers,
payload: payload
};
return result;
}console.log("placeholder");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment