亚马逊Alexa:从SmartHomeSkill lambda控制TCP设备

我有一个用lambda模板创build的SmartHomeSkill。

我有另一个lambda是一个普通的技能function。

我正在使用NodeJS。 我使用Node中的套接字通过TCP直接连接到本地路由器。

一个简单的Lambda使用套接字连接:工程! 技能Lambda使用套接字连接:工作! 技能Lambda使用aws-sdk调用另一个Lambda(来自步骤1):工作! 使用SmartHomeSkill调用套接字:不起作用! 使用SmartHomeSkill调用另一个Lambda:不起作用! 我为所有人使用相同的IAMangular色。 所以,因为情况1到3工作,我认为我的angular色是好的。 我正在使用一个自定义的lambda调用的政策。

我的SmartHomeSkill使用AWSangular色进行身份validation,并使用令牌和一切获得有效的请求。

我的lambda和TCP设备都没有任何身份validationfunction。

TCP设备是自制电子产品。 它适用于普通的lambda和本地软件。

唯一的一件事是:只要我切换到SmartHomeSkill模板什么也没有。 但是,技能本身的作品。 我可以发现设备,Alexas发送调用请求而不抱怨。 我logging了很多东西,所有东西都看起来不错。 在这两种情况下,使用plai TCP套接字或HTTP调用另一个lambda它什么也不做,没有错误,没有响应。

问题:SmartHomeSkill以某种方式使用出站连接受到限制。 但是,如果它连接到其他设备,如Phillips Hue?

这是我的(完美的)inter-lambda接受HTTP负载并重新发送它使用TCP:

var net = require('net'); exports.handler = (event, context, callback) => { console.log(`event=${event}`); var payload = event.payload; sendKnx(payload.ga, +payload.v); // TODO implement callback(null, 'Hello from Lambda'); }; // ---- outbound ----- function sendKnx(ga, v) { var noreply = true; var dir = "W"; if (ga) { console.log('**** Incoming TCP request from Client'); // make numerical ga from convient one var parts = ga.split('/'); if (parts.length === 3) { var hi = +parts[0]; var mi = +parts[1]; var lo = +parts[2]; var gnumerical = hi * 2048 + mi * 256 + lo; // each time we send a package we connect, send, and close in one step // This is EibPC console.log('**** Connect using ' + gnumerical); try { var client = new net.Socket(); console.log('**** Socket created'); client.connect(8888, 'this.is.my.cloud.server', function () { console.log(`**** Send Data ${gnumerical}=${v}`); client.write(`${dir}|${gnumerical}=${v}`); if (noreply){ client.destroy(); console.log('**** Socket destroyed'); } }); client.on('data', function (data) { console.log('Received TCP Response from EibPC: ' + data); client.destroy(); // kill client after server's response }); client.on('close', function () { console.log('TCP Connection to EibPC closed'); }); } catch (Error) { console.error(`**** TCP sending failed: ${Error}`); } } } } 

在我的(完美工作)正规技能拉姆达我要打电话给这样的:

  function forwardLambdaCall(ga, v, context) { console.log('forwardLambdaCall'); var payload = { "payload": { "ga": ga, "v": v } }; lambda.invoke({ FunctionName: 'KNXForwarder', InvocationType: 'RequestResponse', LogType:'Tail', Payload: JSON.stringify(payload) // pass params }, function(error, data) { console.log('Return forwardLambdaCall'); if (error) { console.log('Error forwardLambdaCall' + error); context.done('error', error); } else { console.log('Success forwardLambdaCall' + data); context.succeed({}); } }); } 

“KNXForwarder”是lambda间的名称。 有效负载通过,并按预期工作。 这主要是为了testing目的,我想保证货代正在工作。

如果我在SmartHomeSkill中使用完全相同的呼叫,则不会发生任何事情。

我已经在Alexa论坛上发布了这个名字: https : //forums.developer.amazon.com/questions/58233/control-tcp-device-from-smarthomeskill-lambda.html 。 重复是有目的的,因为我发现其他问题在这里和那里均匀分布,并且不确定是否有正确的方式来接触更广泛的开发人员。

好吧,奇怪,但也许有人可以在这一点上点亮。

首先,问题解决了。

在closuresAlexa的连接之前,我必须发送TCP指令。 在我看来,当入站呼叫以这些TCPstream量之一结束时:

  • context.succeed(…)
  • context.fail(…)

所以我的新处理程序如下所示:

 exports.handler = (event, context, callback) => { console.log(`event=${event}`); var result; if (event.header && event.header.namespace){ switch (event.header.namespace) { case 'Alexa.ConnectedHome.Discovery': handleDiscovery(event, context); break; case 'Alexa.ConnectedHome.Control': result = handleControl(event, context); break; default: context.fail('Something went wrong'); break; } } if (result){ sendKnx(result.payload.ga, result.payload.v, () => context.succeed(result)); } }; 

所以handleControl函数不会结束通信,而是返回我想要提取的值。 我的TCP连接“sendKnx”build立出站通信,一旦该通道closures,Alexa连接就会得到结果。 我正在使用callback(第三个参数),它工作正常。

得到关于通话行为的一些文件将是非常好的。 特别是,这就是为什么我有点抱怨,为什么如果触发是一个SmartHomeSkill相比,一个普通的技能,地狱它performance不同。