SmartHomeApp:Java 上的 reportState 始终返回 INVALID_ARGUMENT

SmartHomeApp: reportState on Java always returning INVALID_ARGUMENT

每当我从我的 SmartHomeApp 上的某个设备获得更新时,我都会 运行 一个 reportState 调用,但我总是 io.grpc.StatusRuntimeException 和 "INVALID_ARGUMENT: Request contains an invalid argument." 消息。

我已按照 https://developers.google.com/actions/smarthome/develop/report-state 和 Java 实施的说明进行操作。唯一的区别是我不会使用与执行调用相同的 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();
   }
}

我猜问题是我没有传递设备名称或任何设备标识符,但它似乎没有关于构建器的方法。

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 并提出问题。