2017-02-11 5 views
1

У меня есть SmartHomeSkill, созданный с помощью шаблона лямбда.Amazon Alexa: Управление устройством TCP от SmartHomeSkill lambda

У меня есть еще одна лямбда, которая является простой функцией умения.

Я использую NodeJS для обоих. Я подключаюсь через TCP напрямую к локальному маршрутизатору, используя сокеты в узле.

Простая Лямбда с использованием гнезд для подключения: работает! A Skill Lambda с использованием сокетов для подключения: работает! Умение Лямбда, вызывающее другую Лямбду (с шага 1) с использованием aws-sdk: работает! Использование SmartHomeSkill для вызова сокетов: не работает! Использование SmartHomeSkill для вызова другой Лямбды: не работает! Я использую одну и ту же роль IAM для всех. Поэтому, поскольку сценарий с 1 по 3 работает, я полагаю, что моя роль хороша. Я использую настраиваемую политику для межлабораторных вызовов.

Мой SmartHomeSkill аутентифицируется с использованием роли AWS, и я получаю действительные запросы с токеном и всем остальным.

Оба устройства, в которых находится между лямбда и TCP, не имеют возможности аутентификации.

TCP-устройство - это самодельная электроника. Он хорошо работает с простым лямбдой и локальным программным обеспечением.

Единственное: как только я переключаюсь на шаблон SmartHomeSkill, ничего не происходит. Однако само умение работает. Я могу обнаружить устройства, и Alexas отправляет запросы без жалоб. Я много разбираюсь, и все выглядит хорошо, потому что выходит наружу. В обоих сценариях, используя plai TCP-сокет или HTTP-вызов на другой лямбда, он ничего не делает, без ошибок, без ответа.

Вопрос: Является ли 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

Хорошо, довольно странно, но, возможно, кто-то может пролить немного света на это.

Во-первых, проблема решена.

Я ДОЛЖЕН отправить инструкцию TCP до того, как соединение с Alexa закрывается.Мне кажется, что, когда входящий вызов завершается с одним из них любой 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 по сравнению с обычным навыком.

Смежные вопросы