我正在研究一个lambda alexa技能处理程序,它与aws IoT中的一个事物阴影集成在一起。我的问题是下面对iotData.getThingShadow的调用似乎没有执行。在回调函数中没有生成任何控制台消息,并且没有填充对象objState。这是代码片段。
// get the shadow for the home-garage-door
console.log('Getting thing shadow');
iotData.getThingShadow(params, function(err, data) {
console.log('Inside of getThingShadow callback');
if (err){
//Handle the error here
console.log('Problem getting the thing shadow');
console.log(err, err.stack);
responseString = "I had trouble contacting the garage door, sorry";
}
else {
console.log("Data back from shadow", JSON.stringify(data));
payload = data.payload;
objState = JSON.parse(payload);
}
});
console.log('After getting the Shadow');
以下是我测试时生成的日志条目。有没有人有任何想法我可能有什么不对?
2018-01-14T22:55:15.564Z fbdde171-f97d-11e7-bc0b-116e508011bd Getting thing shadow
2018-01-14T22:55:16.127Z fbdde171-f97d-11e7-bc0b-116e508011bd After getting the Shadow
2018-01-14T22:55:16.165Z fbdde171-f97d-11e7-bc0b-116e508011bd objState: undefined
这是完整的代码。
/**
Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
/**
*
*/
/**
* App ID for the skill
*/
var APP_ID = 'amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';
/**
* The AlexaSkill prototype and helper functions
*/
var AlexaSkill = require('./AlexaSkill');
var AWS = require('aws-sdk');
/**
* GarageDoorIntentHandler is a child of AlexaSkill.
* To read more about inheritance in JavaScript, see the link below.
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance
*/
var GarageDoorIntentHandler = function () {
AlexaSkill.call(this, APP_ID);
};
// Extend AlexaSkill
GarageDoorIntentHandler.prototype = Object.create(AlexaSkill.prototype);
GarageDoorIntentHandler.prototype.constructor = GarageDoorIntentHandler;
GarageDoorIntentHandler.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
console.log("GarageDoorIntentHandler onSessionStarted requestId: " + sessionStartedRequest.requestId
+ ", sessionId: " + session.sessionId);
// any initialization logic goes here
};
GarageDoorIntentHandler.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
console.log("GarageDoorIntentHandler onLaunch requestId: " + launchRequest.requestId + ", sessionId: " + session.sessionId);
var speechOutput = "Welcome to the Automated Garage door for Alexa, you can say open the garage door or close the garage door";
var repromptText = "You can say open or close the garage door";
response.ask(speechOutput, repromptText);
};
GarageDoorIntentHandler.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
console.log("GarageDoorIntentHandler onSessionEnded requestId: " + sessionEndedRequest.requestId
+ ", sessionId: " + session.sessionId);
// any cleanup logic goes here
};
GarageDoorIntentHandler.prototype.intentHandlers = {
// register custom intent handlers
"moveDoorIntent": function (intent, session, response) {
var responseString = '';
var payload = {};
var objState;
var desiredDoorState = intent.slots.direction.value;
var iotData = new AWS.IotData({endpoint: "XXXXXXXXXXXXXX.iot.us-east-1.amazonaws.com"});
console.log('iotData: ' + JSON.stringify(iotData));
var params = { "thingName" : "<My Thing Name Was Removed for Posting>" };
console.log('Intent: ' + JSON.stringify(intent));
// get the shadow for the home-garage-door
console.log('Getting thing shadow');
iotData.getThingShadow(params, function(err, data) {
console.log('Inside of getThingShadow callback');
if (err){
//Handle the error here
console.log('Problem getting the thing shadow');
console.log(err, err.stack);
responseString = "I had trouble contacting the garage door, sorry";
}
else {
console.log("Data back from shadow", JSON.stringify(data));
payload = data.payload;
objState = JSON.parse(payload);
}
});
console.log('After getting the Shadow');
switch(desiredDoorState.toUpperCase()) {
case 'OPEN':
console.log('objState: ' + JSON.stringify(objState));
switch (objState.state.reported.status.toUpperCase()) {
case 'OPEN':
responseString = "I checked and the door is already open";
break;
case 'CLOSED':
responseString = "Ok, I am closing the garage door";
params.payload = buildObjectState('desired', 'doorActivated', true, 'string');
iotData.updateThingShadow(params, function(err, data) {
if (err){
//Handle the error here
console.log(err, err.stack);
responseString = "I had trouble doing that, sorry";
}
else {
responseString = "Ok, I opened the garage door";
console.log("Data back from shadow", data);
}
});
}
break;
case 'CLOSE':
break;
default:
} // switch
response.tellWithCard(responseString, "Open or Close the Garage Door", responseString);
},
"getDoorStateIntent": function (intent, session, response) {
response.tellWithCard("You can say hello to me!", "You can say hello to me!");
}
};
/**
* Helper function to build the state object for the shadow document
**/
function buildObjectState (section, key, value, format) {
var objState = {state: {}};
objState.state[section] = {};
objState.state[section][key] = value;
if (format === 'object') {
return objState;
} else if (format === 'string') {
return JSON.stringify(objState);
} else return;
}
// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
console.log('received an event');
// Create an instance of the garageDoorIntentHandler.
var garageDoorIntentHandler = new GarageDoorIntentHandler();
garageDoorIntentHandler.execute(event, context);
};
答案 0 :(得分:2)
在Javascript中,代码执行继续到下一行,而不等待异步函数调用完成。您的代码中的错误是因为您在没有值时访问了objState
。
请参阅下面的评论,以便更好地了解它。
// This is called BEFORE iotData.getThingShadow()
console.log('Getting thing shadow');
iotData.getThingShadow(params, function(err, data) {
console.log('Inside of getThingShadow callback');
if (err) {
//Handle the error here
console.log('Problem getting the thing shadow');
console.log(err, err.stack);
responseString = "I had trouble contacting the garage door, sorry";
} else {
console.log("Data back from shadow", JSON.stringify(data));
payload = data.payload;
// This is populated AFTER iotData.getThingShadow() finishes
objState = JSON.parse(payload);
// This is where you put the code that you want to happen AFTER
// iotData.getThingShadow() finishes.
console.log(objState)
}
});
// This will execute without waiting for iotData.getThingShadow() to finish
console.log('After getting the Shadow');
// This will be undefined since iotData.getThingShadow() did NOT return
// yet and objState has NOT been populated
console.log(objState)
因此,要修复它,请在回调函数内部移动您想要发生的代码iotData.getThingShadow()FINISHES。
答案 1 :(得分:2)
看起来你的IOT对象嵌套在Intent中。
我会移动您的IoT阴影并初始化为他们自己的
/Initialize Up Top of Script
AWS.config.region = process.env.IOT_REGION;
var IOT_Data = new AWS.IotData({endpoint: process.env.IOT_ENDPOINT});
var IOT_Thing = process.env.IOT_THING_NAME;
然后我使用辅助函数:
function getShadow(dataObj){
IOT_Data.getThingShadow(dataObj, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
})
}
您的物联网对象现在可以随时随地使用。我已经将这种设置用于多种技能而没有问题。