2017-02-11 94 views
1

我有用lambda模板创建的SmartHomeSkill。亚马逊Alexa:从SmartHomeSkill控制TCP设备lambda

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

我对两者都使用NodeJS。我使用Node中的套接字通过TCP直接连接到本地路由器。

使用套接字连接的纯Lambda:工作! 使用套接字连接的技巧Lambda:工作! 使用aws-sdk调用另一个Lambda(来自步骤1)的技能Lambda:有效! 使用SmartHomeSkill调用套接字:不起作用! 使用SmartHomeSkill调用另一个Lambda:不起作用! 我对所有人都使用相同的IAM角色。因此,因为场景1到3的工作,我认为我的角色是好的。我正在使用一个自定义策略来进行lambda间调用。

我的SmartHomeSkill使用AWS角色进行身份验证,并使用令牌和所有内容获取有效的请求。

这两个,我的lambda和TCP设备没有任何身份验证功能。

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

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

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

-

这是我的(正常使用)间拉姆达接受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”是拉姆达之间的名称。有效负载通过并按预期工作。这主要是为了测试目的,我想确保货运代理工作。

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

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

回答

1

好的,很奇怪,但也许有人可以对此稍微点亮一下。

首先,问题解决了。

我必须在连接来自Alexa的连接关闭之前发送TCP指令。在我看来,当呼入呼叫的其中之一结尾的TCP流量将结束:

  • 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'建立出站通信,一旦该通道关闭,Alexa连接就会得到结果。我正在使用回调(第三个参数),它工作正常。

如果能得到一些有关通话行为的文档将会很棒。尤其是,这就是为什么我有点抱怨,为什么如果触发器是SmartHomeSkill而不是普通技能,那么它的行为会有所不同。