0

I am working on a Google Home Local Fulfillment project following "Enable local fulfillment for smart home Actions" tutorial on the Google Codelabs.

The project is only focus on local control without accessing remote control.

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 as below. statusType: "RESPONSE_UNAVAILABLE" isSuccess: false externalDebugString: "Pubsub failed with 1500ms timeout."

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);
  console.log("Sending request to the smart home device:", payload);

  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);
  });

}

1 Answers1

0

Communicating directly with external service from the local home app is not recommended as it might not be supported across all supported execution environments: https://developers.google.com/assistant/smarthome/concepts/local#execution-environment

The documentation recommends instead to pass additional data required for execution as part of the customData fields of the SYNC response: https://developers.google.com/assistant/smarthome/develop/local#update_sync_response_in_the_cloud_fulfillment

proppy
  • 10,495
  • 5
  • 37
  • 66