SmartHomeApp:Java上的reportState始终返回INVALID_ARGUMENT

时间:2019-06-07 12:20:25

标签: java actions-on-google

每当我从SmartHomeApp上的某个设备获得更新时,我都会运行reportState调用,但我始终是io.grpc.StatusRuntimeException,带有“ INVALID_ARGUMENT:请求包含无效参数”。消息。

我遵循了https://developers.google.com/actions/smarthome/develop/report-state和Java实现上的说明。唯一的区别是,我不使用与execute调用相同的requestId,通常在从物理设备本身进行MQTT更新后将调用reportState方法。

public void reportState(Device device) {
   User user = device.getHub().getUser();
   String requestId = UUID.randomUUID().toString();
   String agentId = user.getId().toString();
   Struct.Builder stateBuilder = Struct.newBuilder();
   if (device.getType().getTraits().contains(GoogleDeviceTrait.ON_OFF)) {
      boolean state = "on".equalsIgnoreCase(device.getState());
      stateBuilder.putFields("on", Value.newBuilder().setBoolValue(state).build());
   }
   if (device.getType().getTraits().contains(GoogleDeviceTrait.OPEN_CLOSE)) {
      int openPercent = device.getState() != null ? Integer.valueOf(device.getState()) : 0;
      stateBuilder.putFields("openPercent", Value.newBuilder().setNumberValue(openPercent).build());
   }
   try {
      smartHomeApp.reportState(ReportStateAndNotificationRequest.newBuilder()
            .setRequestId(requestId)
            .setAgentUserId(agentId)
            .setPayload(StateAndNotificationPayload.newBuilder()
                  .setDevices(ReportStateAndNotificationDevice.newBuilder()
                        .setStates(stateBuilder.build())
                        .build()
                  )
                  .build()
            )
            .build()
      );
   } catch (Exception ex) {
      ex.printStackTrace();
   }
}

我猜测问题是我没有传递设备名称或任何设备标识符,但似乎在构建器上没有为此的方法。

1 个答案:

答案 0 :(得分:1)

Java库使用protobuf Struct对象创建状态对象。在这方面,文档似乎确实是不正确的,就像您要比较代码段创建的Java代码一样:

{
  requestId: '123ABC',
  agentUserId: 'user-123',
  payload: {
    devices: {
      states: {
        on: true,
        openPercent: 50
      }
    }
  }
}

虽然我们提供状态,但没有设备ID,因此尚不清楚此状态属于哪个设备。因此,这将导致参数无效。

您需要将状态对象包装在另一个包含设备标识符的结构中。

Struct.Builder deviceStateBuilder = Struct.newBuilder()
  .putFields("device1", stateBuilder.build()
  .build()

smartHomeApp.reportState(ReportStateAndNotificationRequest.newBuilder()
  .setRequestId(requestId)
  .setAgentUserId(agentId)
  .setPayload(StateAndNotificationPayload.newBuilder()
    .setDevices(ReportStateAndNotificationDevice.newBuilder()
      .setStates(deviceStateBuilder.build())
      .build()
    )
    .build()
  )
.build()

随着Java / Kotlin库中智能家居支持的最初发行,我们将底层的protobuf对象推迟了很多时间,以减少正在创建和审查的API的数量。在前进的过程中,最好看看可以在哪些方面改进开发人员的体验。如果您有任何反馈意见,我邀请您访问图书馆的GitHub page并提出问题。