简体   繁体   中英

Google Actions Smart Home on Lambda not working

I've been trying to get my Google Actions Smart Home (nodejs) working in AWS lambda. However it isn't working. Whenever I connect it on the Google Home app, I just get a message of "Couldn't update the setting...". I've already configured the API gateway correctly and set the Handler to "index.smarthome" as shown in the below image link. Why isn't it working, and how can I get my lambda google action smart home working?

Image Link

My firebase version is working though (modified from the washing machine example at https://codelabs.developers.google.com/codelabs/smarthome-washer/#2 ).

const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');

const app = smarthome();

app.onSync(body => {
  return {
    requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [
          'action.devices.traits.OnOff',
          'action.devices.traits.StartStop',
          'action.devices.traits.RunCycle',
          'action.devices.traits.Modes',
          'action.devices.traits.Toggles',
        ],
        name: {
          defaultNames: ['My Washer'],
          name: 'Washer',
          nicknames: ['Washer']
        },
        deviceInfo: {
          manufacturer: 'Acme Co',
          model: 'acme-washer',
          hwVersion: '1.0',
          swVersion: '1.0.1'
        },
        attributes: {
          pausable: true,
          availableModes: [{
              name: 'load',
              name_values: [{
                  name_synonym: ['load'],
                  lang: 'en'
                }],
              settings: [{
                  setting_name: 'small',
                  setting_values: [{
                      setting_synonym: ['small'],
                      lang: 'en'
                    }]
                  }, {
                  setting_name: 'large',
                  setting_values: [{
                      setting_synonym: ['large'],
                      lang: 'en'
                    }]
                }],
              ordered: true
            }],
          availableToggles: [{
              name: 'Turbo',
              name_values: [{
                  name_synonym: ['turbo'],
                  lang: 'en'
              }]
          }]
        }
    }]
    }
  };
});

app.onExecute((body) => {
  const {requestId} = body;
  const payload = {
    commands: [{
      ids: [],
      status: 'SUCCESS',
      states: {
        online: true,
      },
    }],
  };
  for (const input of body.inputs) {
    for (const command of input.payload.commands) {
      for (const device of command.devices) {
        const deviceId = device.id;
        payload.commands[0].ids.push(deviceId);
        for (const execution of command.execution) {
          const execCommand = execution.command;
          const {params} = execution;
          switch (execCommand) {
            case 'action.devices.commands.OnOff':
              payload.commands[0].states.on = params.on;
              break;
            case 'action.devices.commands.StartStop':
              payload.commands[0].states.isRunning = params.start;
              break;
            case 'action.devices.commands.PauseUnpause':
              payload.commands[0].states.isPaused = params.pause;
              break;
            case 'action.devices.commands.SetModes':
              break;
            case 'action.devices.commands.SetToggles':
              break;
          }
        }
      }
    }
  }
  return {
    requestId: requestId,
    payload: payload,
  };
});

exports.smarthome = functions.https.onRequest(app);

And here is the code that I used in my AWS lambda function. I referenced https://github.com/actions-on-google/actions-on-google-nodejs & creating dialogflow v2 project with serverless to make it lambda compatible. The main difference between the lambda and firebase versions is the "exports.smarthome" code.


const {smarthome} = require('actions-on-google');

const app = smarthome();

app.onSync(body => {
  return {
    requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [
          'action.devices.traits.OnOff',
          'action.devices.traits.StartStop',
          'action.devices.traits.RunCycle',
          'action.devices.traits.Modes',
          'action.devices.traits.Toggles',
        ],
        name: {
          defaultNames: ['My Washer'],
          name: 'Washer',
          nicknames: ['Washer']
        },
        deviceInfo: {
          manufacturer: 'Acme Co',
          model: 'acme-washer',
          hwVersion: '1.0',
          swVersion: '1.0.1'
        },
        attributes: {
          pausable: true,
          availableModes: [{
              name: 'load',
              name_values: [{
                  name_synonym: ['load'],
                  lang: 'en'
                }],
              settings: [{
                  setting_name: 'small',
                  setting_values: [{
                      setting_synonym: ['small'],
                      lang: 'en'
                    }]
                  }, {
                  setting_name: 'large',
                  setting_values: [{
                      setting_synonym: ['large'],
                      lang: 'en'
                    }]
                }],
              ordered: true
            }],
          availableToggles: [{
              name: 'Turbo',
              name_values: [{
                  name_synonym: ['turbo'],
                  lang: 'en'
              }]
          }]
        }
    }]
    }
  };
});

app.onExecute((body) => {
  const {requestId} = body;
  const payload = {
    commands: [{
      ids: [],
      status: 'SUCCESS',
      states: {
        online: true,
      },
    }],
  };
  for (const input of body.inputs) {
    for (const command of input.payload.commands) {
      for (const device of command.devices) {
        const deviceId = device.id;
        payload.commands[0].ids.push(deviceId);
        for (const execution of command.execution) {
          const execCommand = execution.command;
          const {params} = execution;
          switch (execCommand) {
            case 'action.devices.commands.OnOff':
              payload.commands[0].states.on = params.on;
              break;
            case 'action.devices.commands.StartStop':
              payload.commands[0].states.isRunning = params.start;
              break;
            case 'action.devices.commands.PauseUnpause':
              payload.commands[0].states.isPaused = params.pause;
              break;
            case 'action.devices.commands.SetModes':
              break;
            case 'action.devices.commands.SetToggles':
              break;
          }
        }
      }
    }
  }
  return {
    requestId: requestId,
    payload: payload,
  };
});

exports.smarthome = function(event, context, callback) {
  app.handler(event, {})
    .then((res) => {
      if (res.status != 200) {
        callback(null, {
          "fulfillmentText": `I got status code: ${res.status}`
        });
      } else {
        callback(null, res.body);
      }
    }).catch((e) => {
      callback(null, {
        "fulfillmentText": `There was an error\n${e}`
      });
    });
};

Check your AWS CloudWatch logs and see what happens when the lambda is called. You can print to stdout in your lambda and have it show up in these logs.

除了Cloudwatch日志外,您还可以查看Stackdriver日志。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM