报告状态因未经授权的 Google Home 操作而失败

问题描述

我正在我的 onExecute 处理程序中发送一个 report state 请求。它失败了:

io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token,login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
   at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:233)
   at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:214)
   at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:139)
   at com.google.home.graph.v1.HomeGraphApiServiceGrpc$HomeGraphApiServiceBlockingStub.reportStateAndNotification(HomeGraphApiServiceGrpc.java:425)
   at com.google.actions.api.smarthome.SmartHomeApp.reportState(SmartHomeApp.kt:132)
[snip]

我不知道这是怎么可能的,因为我使用 SmartHomeApp 发出请求,同一个 SmartHomeApp 接收同步、查询、执行、断开连接。这是我的代码

var state = new HashMap();
state.put("openPercent",50); // etc
SmartHomeApp app = ... // this is what received the onExecute
app.reportState(ReportStateAndNotificationRequest.newBuilder()
    .setRequestId(request.requestId) // onExecute requestId
    .setAgentUserId(userId) // hardcoded user
    .setPayload(StateAndNotificationPayload.newBuilder()
        .setDevices(ReportStateAndNotificationDevice.newBuilder()
            .setStates(Struct.newBuilder()
                // tovalue converts the state to a protobuf value,see data below
                .putFields("kitchenDoor",UtilProtoBuf.tovalue(state))
                .build()
            ).build()
        ).build()
    ).build());

toStringReportStateAndNotificationRequest,以便您可以查看数据:

request_id: "16744804305948869781"
agent_user_id: "123"
payload {
  devices {
    states {
      fields {
        key: "kitchenDoor"
        value {
          struct_value {
            fields {
              key: "openPercent"
              value {
                number_value: 50.0
              }
            }
          }
        }
      }
    }
  }
}

解决方法

虽然您可以接收入站请求,但您无法立即将出站请求返回给 Google。首先你必须activate the HomeGraph API and download a service account key

然后将其添加到您的 SmartHomeApp

  // Get service account key from file
  FileInputStream stream = new FileInputStream("service-account-key.json");
  GoogleCredentials credentials = GoogleCredentials.fromStream(stream);
  mySmartHomeApp.setCredentials(credentials);

这应该可以解决您的授权问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...