SmartHomeApp: reportState на Java всегда возвращает INVALID_ARGUMENT - PullRequest
1 голос
/ 07 июня 2019

Всякий раз, когда я получаю обновление от какого-либо устройства на моем SmartHomeApp, я запускаю вызов reportState, но я всегда являюсь io.grpc.StatusRuntimeException с «INVALID_ARGUMENT: Запрос содержит недопустимый аргумент».message.

Я следовал инструкции на https://developers.google.com/actions/smarthome/develop/report-state и реализации Java.Единственное отличие состоит в том, что я не буду использовать тот же requestId, что и при вызове execute, поскольку обычно метод reportState вызывается после обновления MQTT с самого физического устройства.

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 Ответ

1 голос
/ 07 июня 2019

Библиотека Java использует объекты protobuf Struct для создания объекта состояния. В этом отношении документация действительно неверна, как если бы вы сравнивали код Java, создаваемый вашим фрагментом:

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

Хотя мы предоставляем состояния, идентификатор устройства отсутствует, поэтому неясно, к какому устройству относится это состояние. Таким образом, это приведет к неверному аргументу.

Вам нужно будет обернуть ваш объект состояния в другую структуру, содержащую идентификатор устройства.

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 и отправить заявку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...