smart-home-local icon indicating copy to clipboard operation
smart-home-local copied to clipboard

Pubsub failed with 1500ms timeout

Open fanwu8184 opened this issue 4 years ago • 1 comments

I need to run a query on my firestore database at executeHandler before I run this.app.getDeviceManager().send(deviceCommand).

This will give me timeout errors sometimes as below. Screen Shot 2021-01-13 at 5 24 33 PM

Is there a way I can set the timeout more than 1500ms?

The following is my code of executeHandler:

executeHandler(request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> { // TODO: Implement local execution console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

const command = request.inputs[0].payload.commands[0];
const execution = command.execution[0];
const response = new Execute.Response.Builder().setRequestId(request.requestId);

const promises: Array<Promise<void>> = command.devices.map(async (device) => {
  console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

  // Convert execution params to a string for the local device
  const params = execution.params as IFireplaceParams;
  const tcpMsg = 'MWIB2,02';
  const payload = this.stringToHex(tcpMsg);

  const firebaseDataObj = await this.queryFirebase(device.id);
  console.log("firebaseDataObj:", JSON.stringify(firebaseDataObj));

  // Construct a local device command over TCP
  const deviceCommand = new DataFlow.TcpRequestData();
  deviceCommand.requestId = request.requestId;
  deviceCommand.deviceId = device.id;
  deviceCommand.data = payload;
  deviceCommand.port = SERVER_PORT;
  deviceCommand.operation = Constants.TcpOperation.WRITE;

  try {
    const result = await this.app.getDeviceManager().send(deviceCommand);
    console.log("Sending deviceCommand result:", JSON.stringify(result));
    const state = { online: true };
    response.setSuccessState(result.deviceId, Object.assign(state, params));
  } catch (err) {
    err.errorCode = err.errorCode || 'invalid_request';
    response.setErrorState(device.id, err.errorCode);
    console.error('An error occurred sending the command', err.errorCode);
  }
});

return Promise.all(promises)
  .then(() => {
    return response.build();
  })
  .catch((e) => {
    const err = new IntentFlow.HandlerError(request.requestId, 'invalid_request', e.message);
    return Promise.reject(err);
  });

}

fanwu8184 avatar Jan 14 '21 04:01 fanwu8184

@fanwu8184 can you confirm how you use the data returned by firebase, I don't see firebaseDataObj being used in the command snippet you've pasted.

If you need data associated to a device during EXECUTE handler, the best practice is to return per-device customData in the cloud fulfillment SyncResponse, see https://developers.google.com/assistant/smarthome/develop/local#update_sync_response_in_the_cloud_fulfillment

proppy avatar Jan 21 '21 13:01 proppy