Alexa 智能家居:设备不断显示“出现问题”

问题描述 投票:0回答:1

我们能够链接我们的技能并发现已连接的设备,但发现后,所有设备都设置为“关闭”,并且顶部显示错误消息“存在问题”。

这是我们的 lambda 函数:(当前仅处理发现和状态响应):

/**
 * 
 */
var AUTH_KEY = process.env.AUTH_KEY;
var SET_DEVICE_CONFIG_URL = process.env.SET_DEVICE_CONFIG_URL;
var GET_DEVICE_STATE_URL = process.env.GET_DEVICE_STATE_URL;
var axios = require('axios')
 
var rp = require('request-promise');
 
const CONTROL_POWER = 'Alexa.PowerController';
// const TURNOFF_OR_ON = 'Alexa.ConnectedHome.Control';
const CONTROL_LOCK = 'Alexa.LockController';
const DISCOVERY = 'Alexa.Discovery';
const DISCOVERY_RESPONSE = 'Discover.Response';
const ALEXA = 'Alexa';
const RESPONSE = 'Response';
const STATE_REPORT = 'Alexa.ReportState';
const ERROR_RESPONSE = 'ErrorResponse';
 
const PAYLOAD_V = '3';
 
/**
 * Main entry point.
 * Incoming events from Alexa Lighting APIs are processed via this method.
 */
exports.handler = async function(request, context) {
    let namespace = "";
    let header = "";
    console.log('Input', request);
    // console.log('Payload', request.directive.payload);
    if(request.directive) {
        namespace = request.directive.header.namespace;
        header = request.directive.header;
    }
    else if (request.header.namespace) {
        namespace = request.header.namespace
        header = request.header;
    }
    console.log(namespace, header);
    switch (namespace) {
    case DISCOVERY:
        let response = await handleDiscovery(request, context);
        console.log(response.data);
        return response;
        break;
    case CONTROL_POWER:
        console.log("HEADER", header);
        console.log("CONTROL POWER HIT");
        break;
    case CONTROL_LOCK:
        handleControl(request, context);
        break;
    case ALEXA:
        let sr_response = await handleStateRequest(request, context);
        console.log(sr_response);
        return sr_response
        break;
    case STATE_REPORT:
        console.log("STATE REPORT");
        console.log("SR REQUEST", request);  
        handleStateRequest(request, context);
    default:
        console.log('Err', 'No supported namespace: ' + namespace);
        // callback('Something went wrong');
        break;
    }
};
 
 
/**
 * This method is invoked when we receive a "Discovery" message from Alexa Smart Home Skill.
 * We are expected to respond back with a list of appliances that we have discovered for a given
 * customer. 
 */
 
 
async function handleDiscovery(request, context) {
    let accessToken = request.directive.payload.scope.token;
    var event = {
            header: {
                namespace: DISCOVERY,
                name: DISCOVERY_RESPONSE,
                payloadVersion: PAYLOAD_V,
                messageId: createMessageId()
            },
            payload: { 
                endpoints: ""
            }
    };
    
  try {
    let URL = `https://MYURL/api/getdevices?accessToken=${accessToken}`;
    console.log(URL);
    const response = await axios.get(URL);
 
    console.log(response);
    event.payload.endpoints = response.data.devices;
    return {
         event
     };
  } catch (error) {
      console.log(error);
    return {
      statusCode: 500,
      body: JSON.stringify({ message: 'Error occurred while processing the request.' })
    };
  }
   
}
 
/**
 * STATE REQUEST HANDLER
 * */
 
 async function handleStateRequest(request, context) {
    console.log("REQUEST : ", request);
      try {
    // Extract the directive from the event
    const directive = request.directive;
    const scope_ = request.directive.endpoint.scope;
    const cookie_ = request.directive.endpoint.cookie;
    const accessToken = request.directive.endpoint.scope.token;
        // Check if the directive type is Alexa.ReportState
    if (directive.header.namespace === 'Alexa' && directive.header.name === 'ReportState') {
      // Handle the ReportState directive
      const payload = directive.payload;
      const {correlationToken} = directive.header;
      const {endpointId} = directive.endpoint;
 
      const URL = `https://MYURL/api/reportstate?accessToken=${accessToken}`;
      const url_response = await axios.post(URL, directive);
 
      // Handle the response from the external URL if necessary
      console.log('Response:', url_response);
      console.log('Response:', url_response.data);
 
      // Build the response
      const response = {
        event: {
          header: {
            namespace: 'Alexa',
            name: 'StateReport',
            messageId: createMessageId(),
            correlationToken: correlationToken,
            payloadVersion: '3'
          },
          endpoint: {
            scope: scope_,
            endpointId: endpointId,
            cookie: cookie_,
          },
          payload: {},
          context: {
            properties: [
              {
                namespace: "Alexa.PowerController",
                name: "powerState",
                value: url_response.data.data.value,
                timeOfSample: url_response.data.data.time,
                uncertaintyInMilliseconds: 1000
              },
              {
                namespace: "Alexa.EndpointHealth",
                name: "connectivity",
                value: {
                  value: "OK"
                       },
                timeOfSample: url_response.data.data.time,
                uncertaintyInMilliseconds: 1000
              }
                
              ]
            }
        }
      };
    console.log(response);
    console.log(response.event.endpoint);
    console.log(response.event.context);
      return response;
    }
 
    // If the directive is not Alexa.ReportState, return an error response
    return createErrorResponse('INVALID_DIRECTIVE', 'This skill only supports Alexa.ReportState directives.');
  } catch (error) {
    console.error('Error handling directive:', error);
    return createErrorResponse('INTERNAL_ERROR', 'An internal error occurred while handling the directive.');
  }
 
};
 
//TRUNCATED FOR READABILITY

这是我们的指示性回应:

{
            header: {
                namespace: Alexa.Discovery,
                name: Discover.Response,
                payloadVersion: 3,
                messageId: createMessageId()
            },
            payload: { 
                endpoints: [
        {
            "endpointId": "632d46a5f6755c965fa7e4df",
            "manufacturerName": "TESTABC",
            "modelName": "STS001",
            "version": "VER01",
            "friendlyName": "SOCKET 1",
            "description": "Wifi Socket",
            "displayCategories": [
                "SMARTPLUG"
            ],
            "capabilities": [
                {
                    "type": "AlexaInterface",
                    "interface": "Alexa.PowerController",
                    "version": "3",
                    "properties": {
                        "supported": [
                            {
                                "name": "powerState"
                            }
                        ],
                        "proactivelyReported": true,
                        "retrievable": true
                    }
                },
                {
                    "type": "AlexaInterface",
                    "interface": "Alexa.EndpointHealth",
                    "version": "3",
                    "properties": {
                        "supported": [
                            {
                                "name": "connectivity"
                            }
                        ],
                        "proactivelyReported": true,
                        "retrievable": true
                    }
                }
            ],
            "cookie": {}
        }
}]}

这是我们的状态响应:

{
  event: {
    header: {
      namespace: 'Alexa',
      name: 'StateReport',
      messageId: '0693d096-2d13-442d-8d9f-41c65de4592e',
      correlationToken: 'REMOVED FOR BREVITY',
      payloadVersion: '3'
    },
    endpoint: {
      scope:
     {
    type: 'BearerToken',
    token: 'REMOVED FOR BREVITY'
     },
      endpointId: '632d46a5f6755c965fa7e4df',
      cookie: {}
    },
    payload: {},
    context: { properties: [ {
   
      namespace: 'Alexa.PowerController',
      name: 'powerState',
      value: 'OFF',
      timeOfSample: '2023-05-17T09:24:31.562Z',
      uncertaintyInMilliseconds: 1000
    },
    {
   
      namespace: 'Alexa.EndpointHealth',
      name: 'connectivity',
      value: {
   
         value : 'OK'
      },
      timeOfSample: '2023-05-17T09:24:31.562Z',
      uncertaintyInMilliseconds: 1000
    }] }
  }
}

然而,我们所有的设备都呈灰色,并在顶部显示“出现问题”消息。 Lambda 函数能够从服务器获取响应并将其发送。 alexa screenshot with problem message

node.js aws-lambda alexa
1个回答
0
投票

问题是,在您的技能的

'StateReport'
JSON 响应中,所有内容都嵌套在
'event'
对象下。

简而言之,期望技能的 JSON 响应包含两个单独的顶级对象

'event'
'context'
,而在此示例中,您的
'context'
对象错误地位于
'event'
内,为
'event.context'

使用您的 JSON 响应作为起点,我对其进行了修改,以将

'event'
'context'
对象彼此分开,如下所示:

{
    "context": {
        "properties": [
            {
                "name": "powerState",
                "namespace": "Alexa.PowerController",
                "timeOfSample": "2023-05-17T09:24:31.562Z",
                "uncertaintyInMilliseconds": 1000,
                "value": "OFF"
            },
            {
                "name": "connectivity",
                "namespace": "Alexa.EndpointHealth",
                "timeOfSample": "2023-05-17T09:24:31.562Z",
                "uncertaintyInMilliseconds": 1000,
                "value": {
                    "value": "OK"
                }
            }
        ]
    },
    "event": {
        "endpoint": {
            "cookie": {},
            "endpointId": "632d46a5f6755c965fa7e4df",
            "scope": {
                "token": "REMOVED FOR BREVITY",
                "type": "BearerToken"
            }
        },
        "header": {
            "correlationToken": "REMOVED FOR BREVITY",
            "messageId": "0693d096-2d13-442d-8d9f-41c65de4592e",
            "name": "StateReport",
            "namespace": "Alexa",
            "payloadVersion": "3"
        },
        "payload": {}
    }
}

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.