node.js Https call return undefined.Amazon AWS - PullRequest
0 голосов
/ 17 мая 2018

Изменить.Код теперь обновляется с первого поста:

"Теперь он работает следующим образом: первый раз при запуске pooltemp не определен. Если запустить еще раз сразу, я получу pooltemp = 30 (что является новой температурой).по крайней мере, говорит о том, что вызов вещейпик работает. Если я запустлю его снова через несколько минут, он снова не будет определен в первый раз. Кажется, что AWS сохраняет значение некоторое время после завершения функции. "

Ясовершенно новый для node.js, но со следующим кодом, который я написал в основном с помощью cut & paste.Он работает в Amazon AWS, отвечая на вызов Alexa.Я пытаюсь прочитать канал вещей, чтобы получить температуру в моем пуле. (URL возвращает json с температурой. Канал обновляется с помощью esp8266, который измеряет пул и отправляет его в канал. К сожалению, я получаю только неопределенный пулЯ создаю функцию getCall (), чтобы получить температуру из thinspeak. Когда я использую переменную pooltemp в handlerinput, она не определена. Все остальное работает нормально. Если я жестко запишу pooltemp в handlerinput, я получу ответ, который мне нужен. Код выглядит следующим образомЯ очень благодарен за помощь. Спасибо:

/* eslint-disable  func-names */
/* eslint-disable  no-console */



const Alexa = require('ask-sdk');


var https = require('https');
var pooltemp;


  getCall();




//ThingSpeak Data Access

function getCall() {
  var options = {
    protocol: 'https:', 
    host: 'api.thingspeak.com',
    path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
    method: 'GET'
  };

  var getReq = https.request(options, function(res) {
    console.log("\nstatus code: ", res.statusCode);
    var jsonData = '';
    res.on('data', function(data) {
        jsonData += data;
    });
    res.on('end', function() {
      console.log('We have all the data');
      var result = JSON.parse(jsonData);
      console.log('data: ', result);
      console.log('Pool temperature: ', result.feeds[0].field1);
      // Save the latest pool temperature.
      pooltemp = result.feeds[0].field1;
    });
  });

  //end the request
  getReq.end();
  getReq.on('error', function(err) {
    console.log("Error: ", err);
  });
}


const GetNewFactHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest' ||
      (request.type === 'IntentRequest' &&
        request.intent.name === 'GetNewFactIntent');
  },



  handle(handlerInput) {


    //  var pooltemp = 22;
    var factIndex;
    const factArr = data;
    if (pooltemp <= 15) {
      factIndex = 0;
    }
    if (15 < pooltemp == pooltemp < 20) {
      factIndex = 1;
    }
    if (20 <= pooltemp == pooltemp < 25) {
      factIndex = 2;
    }
    if (pooltemp >= 25) {
      factIndex = 3;
    }


    const randomFact = factArr[factIndex];
    const speechOutput = 'Hold on a second, I will check for you.<break time="1s"/>Today it is ' + pooltemp + ' degrees in the pool. ' + randomFact;
    return handlerInput.responseBuilder
      .speak(speechOutput)
      .withSimpleCard(SKILL_NAME, randomFact)
      .getResponse();

  },
};

const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      (request.intent.name === 'AMAZON.CancelIntent' ||
        request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s today temperature: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';

const data = [
  'It is freezing cold. Swimming only for idiots',
  'It is not for whimps, but you may swim. Do you dare go for it?',
  'Wich is a nice temperature for a norwegian.',
  'This is quite comfortable and a swim should be really nice ',

];

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    GetNewFactHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

В настоящее время ваша функция getCall () выполняется асинхронно, поэтому pooltemp не определено. Из-за асинхронности javascript перед успешным выполнением функции getCall () она переходит к условию

Здесь я внес изменения в функцию getCall , используя обратный вызов javascript. Также в методе GetNewFactHandler handle () после успешного выполнения функции getCall будут выполняться остальные условия.

/* eslint-disable  func-names */
/* eslint-disable  no-console */
const Alexa = require('ask-sdk');

var https = require('https');

//ThingSpeak Data Access
function getCall(callback) {
  //initialize options values, the value of the method can be changed to POST to make https post calls
  var options = {
    protocol: 'https:', 
    host: 'api.thingspeak.com',
    path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
    method: 'GET'
  };

  //making the https get call
  https.request(options, function(res) {
    console.log("\nstatus code: ", res.statusCode);
    let data = ''

    // A chunk of data has been recieved from request stream.  
    res.on('data', function(chunk) {
        data += chunk;
    });

    // Once the whole response has been received, return response as callback
    res.on('end', () => {
      console.log('We have all the data');
      var result = JSON.parse(data);
      console.log('data: ', result);
      console.log('Pool temperature: ', result.feeds[0].field1);
      // Save the latest pool temperature.
      const poolTemp = result.feeds[0].field1;
      callback(null, poolTemp);
    });
  })
  .on('error', function(err) {
    callback(err);
  });
}

const GetNewFactHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest' ||
      (request.type === 'IntentRequest' &&
        request.intent.name === 'GetNewFactIntent');
  },

  handle(handlerInput) {

    getCall((err, pooltemp) => {
        //Error handling implementation
        if(err) {
            console.log("Error: ", err);    
        }
        //Validating condition after successful response from getCall       
        //  var pooltemp = 22;
        var factIndex;
        const factArr = data;
        if (pooltemp <= 15) {
          factIndex = 0;
        }
        if (15 < pooltemp == pooltemp < 20) {
          factIndex = 1;
        }
        if (20 <= pooltemp == pooltemp < 25) {
          factIndex = 2;
        }
        if (pooltemp >= 25) {
          factIndex = 3;
        }

        const randomFact = factArr[factIndex];
        const speechOutput = 'Hold on a second, I will check for you.<break time="1s"/>Today it is ' + pooltemp + ' degrees in the pool. ' + randomFact;
        return handlerInput.responseBuilder
          .speak(speechOutput)
          .withSimpleCard(SKILL_NAME, randomFact)
          .getResponse();
    }
  },
};

const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      (request.intent.name === 'AMAZON.CancelIntent' ||
        request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s today temperature: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';

const data = [
  'It is freezing cold. Swimming only for idiots',
  'It is not for whimps, but you may swim. Do you dare go for it?',
  'Wich is a nice temperature for a norwegian.',
  'This is quite comfortable and a swim should be really nice ',

];

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    GetNewFactHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();
0 голосов
/ 17 мая 2018

Я проверил это и внес несколько изменений в функцию getCall (), теперь она должна работать:

function getCall() {
  var options = {
    protocol: 'https:', 
    host: 'api.thingspeak.com',
    path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
    method: 'GET'
  }

  var getReq = https.request(options, function(res) {
    console.log("\nstatus code: ", res.statusCode);
    var jsonData = '';
    res.on('data', function(data) {
        jsonData += data;
    });
    res.on('end', function() {
       console.log('We have all the data');
       var result = JSON.parse(jsonData);
       console.log('data: ', result);
       console.log('Pool temperature: ', result.feeds[0].field1);
       // Save the latest pool temperature.
       poolTemp = result.feeds[0].field1;
    });
  });

  //end the request
  getReq.end();
  getReq.on('error', function(err) {
    console.log("Error: ", err);
  });
}

getCall();

Вы также можете попробовать это в начале вашего скрипта:

getCall();
setInterval(getCall, 10000);

Это будет обновлять температуру бассейна каждые 10 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...