Hello
Im looking for some help with developing a skill using amazon’s aws lambda and skill tools. Following this tutorial (https://medium.com/@thebelgiumesekid/how-to-create-an-alexa-enabled-smart-home-with-particle-photon-part-2-8590314688e8) i was able to get the lambda function up and running and even turn on an led via “Alexa, turn led on” and subsequently turn it off the same way. But now im having trouble implement the same function to turn on two different leds using the same kind of method.
here is the code i code to work with alexa:
#define PIN_LED D4
#define BAUD_RATE 9600
#define LOOP_DELAY 1000
bool isLedOn = false;
void setup_serial(void) {
Serial.begin(BAUD_RATE);
}
void setup_pins(void) {
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
}
void set_led_on(void) {
digitalWrite(PIN_LED, HIGH);
isLedOn = true;
}
void set_led_off(void) {
digitalWrite(PIN_LED, LOW);
isLedOn = false;
}
bool handler_led(String state) {
Serial.printf("Event triggered! state: %s\n", state.c_str());
if (state == "ON") {
set_led_on();
} else if (state == "OFF") {
set_led_off();
} else {
return false;
}
return true;
}
void setup_events(void) {
// Expose the LED state to the cloud
Particle.variable("isLedOn", isLedOn);
// Expose a function to change state
Particle.function("setLed", handler_led);
}
void setup(void) {
setup_serial();
setup_pins();
setup_events();
}
void loop(void) {
Serial.println("looping");
delay(LOOP_DELAY);
}
and this is the lambda function which i uploaded for it to work with the led:
const Particle = require('particle-api-js');
const particle = new Particle();
module.exports = {
setDeviceState(deviceId, state, token) {
return particle.callFunction({
deviceId: deviceId,
name: 'setLed',
argument: state,
auth: token
}).then((result) => {
return result.body.return_value === 1 ? 'ON' : 'OFF';
}).catch((error) => {
return null;
});
},
getDeviceState(deviceId, token) {
return particle.getVariable({ deviceId: deviceId, name: 'isLedOn', auth: token });
}
};
im trying to use the same lambda function to implement my own actions and have alexa be able to control two leds in the following code:
const int frontlight = D4; //front light
const int backlight = A2; //back light
void setup() {
pinMode(frontlight, OUTPUT);
pinMode(backlight, OUTPUT);
Particle.function("Front-Lights", FrontLights);
Particle.function("Back-Lights", Backlights);
}
void loop() {
}
int FrontLights(String ledCommand) {
String convertedCommand = ledCommand.toUpperCase();
if(convertedCommand == "ON FRONT") {
digitalWrite(frontlight, HIGH);
return(1);
} else if(convertedCommand == "OFF FRONT") {
digitalWrite(frontlight, LOW);
return(0);
}
else {
return(-1);
}
}
int Backlights(String ledCommands) {
String convertedCommand= ledCommands.toUpperCase();
if(convertedCommand == "ON BACK") {
digitalWrite(backlight, HIGH);
return(1);
} else if(convertedCommand== "OFF BACK") {
digitalWrite(backlight, LOW);
return(0);
}
else {
return(-1);
}
}
Whn i replaced the function names in the lambda function it does nothing. Alexa cant even pick it up. Any help please.
THIS IS THE index.js
const DEVICE_ID = '38003b000d47373334323233';
const Particle = require('./Particle');
exports.handler = async (request, context, callback) => {
log('DEBUG', `Handler request: ${JSON.stringify(request)}`);
log('DEBUG', `Handler context: ${JSON.stringify(context)}`);
const response = await handleRequest(request);
log('DEBUG', `Response: ${JSON.stringify(response)}`);
callback(null, response);
};
function handleRequest(request) {
let { namespace, name } = request.directive.header;
switch (namespace) {
case 'Alexa.Discovery':
return handleDiscovery(request);
case 'Alexa.PowerController':
return handlePowerControl(request);
case 'Alexa':
if (name === 'ReportState') {
return handleStateReport(request);
}
return {};
default:
log('ERROR', `Unknown namespace ${namespace}`);
return {};
}
}
function handleDiscovery(request) {
let header = request.directive.header;
header.name = 'Discover.Response';
return {
event: {
header: header,
payload: {
endpoints: [{
endpointId: 'demo_id',
manufacturerName: 'Wonka Chocolate Factory',
friendlyName: 'Particle Device',
description: 'Particle Device',
displayCategories: ['SWITCH'],
capabilities: [
{
type: 'AlexaInterface',
interface: 'Alexa',
version: '3'
},
{
interface: 'Alexa.PowerController',
version: '3',
type: 'AlexaInterface',
properties: {
supported: [{
name: 'powerState'
}],
retrievable: true,
proactivelyReported: false
}
}
]
}]
}
}
};
}
async function handlePowerControl(request) {
log('DEBUG', 'Triggered PowerControl');
const token = getParticleTokenFromRequest(request);
let stateToSet;
// Set correct state based on the Alexa directive
if (request.directive.header.name === 'TurnOn') {
stateToSet = 'ON';
} else {
stateToSet = 'OFF';
}
// Set the state on the device, also get the actual state (should be the same)
const actualState = await Particle.setDeviceState(DEVICE_ID, stateToSet, token);
let { header, endpoint } = request.directive;
header.namespace = 'Alexa';
header.name = 'Response';
const returnContext = {
properties: [ {
namespace: 'Alexa.PowerController',
name: 'powerState',
value: actualState,
timeOfSample: (new Date()).toISOString(),
uncertaintyInMilliseconds: 0
} ]
};
const response = {
context: returnContext,
event: {
header: header,
endpoint: endpoint,
payload: {}
}
};
log('DEBUG', `Set State: ${JSON.stringify(response)}`);
return response;
}
async function handleStateReport(request) {
let { header, endpoint } = request.directive;
header.name = 'StateReport';
const token = getParticleTokenFromRequest(request);
const stateBool = await Particle.getDeviceState(DEVICE_ID, token);
const returnContext = {
properties: [{
namespace: 'Alexa.PowerController',
name: 'powerState',
value: stateBool.body.result ? 'ON' : 'OFF',
timeOfSample: stateBool.body.coreInfo.last_heard,
uncertaintyInMilliseconds: 0
}]
};
const response = {
context: returnContext,
event: {
header: header,
endpoint: endpoint,
payload: {}
}
};
log('DEBUG', `State Response: ${JSON.stringify(response)}`);
return response;
}
function getParticleTokenFromRequest(request) {
// request.directive.endpoint.scope.token OR request.directive.payload.scope.token
const tokenData = (request || {}).directive || {};
return ((tokenData.endpoint || tokenData.payload || {}).scope || {}).token;
}
function log(type, value) {
console.log(`${type}: ${value}`);
}