'Google IOT: Identify the device is back online after sendCommandtoDevice failure

By following this guide Sending commands to devices.

// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const commandMessage = 'message for device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const iot = require('@google-cloud/iot');
const iotClient = new iot.v1.DeviceManagerClient({
  // optional auth parameters.
});

const formattedName = iotClient.devicePath(
  projectId,
  cloudRegion,
  registryId,
  deviceId
);
const binaryData = Buffer.from(commandMessage);
const request = {
  name: formattedName,
  binaryData: binaryData,
};

try {
  const responses = await iotClient.sendCommandToDevice(request);

  console.log('Sent command: ', responses[0]);
} catch (err) {
  console.error('Could not send command:', err);
}

I have this function running on Google Cloud Function (thanks Firebase, I love you), sending the command to Google IoT Devices created by Mongoose OS + Google IoT Core framework.

It works as expected most of the time. Now I am looking to improve the system when the device is not responding.

For many reasons, the device may temporarily be lost connectivity and consequent loss a command (see image below):

Google Cloud Function Log Screenshot with error "Error: 9 FAILED_PRECONDITION" Device is not connected."

In this case, the device was not reachable for a moment (for example, poor mobile internet signal, or internet route issues, anyways).

Is there somehow I can trigger a function when the device is back online and available?

My purpose is, if the user sent a command to a device when the device is not responding, I would like to send the command again automatically. Guess what may happen if the user needs to turn off a motor and the device lose the command?

But keep in mind the device is not "disconnected" from the Google IOT MQTT server. The connections are still alive and it is up and running, connected through good wifi signal to fiber internet. The device cannot realize that something wrong happens from the server-side.

I also "guess" the device needs to send a ping before the server understands it is not alive based on MQTT keep-alive interval, but I don't know how to check that.



Solution 1:[1]

To detect and react when a device comes online and goes offline:

  1. Create a Sink in Cloud Logging
  2. Put this query in the new Sink: resource.type="cloudiot_device" AND jsonPayload.eventType=("CONNECT" OR "DISCONNECT")
  3. Send the Sink to Pub/Sub
  4. Create a Cloud Function
  5. Create a Push subscription from Pub/Sub to the Cloud Function

Then you can process the log message in the function and act accordingly:

  • The device "friendly" ID is into labels.device_id
  • The event type is in jsonPayload.eventType

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 eddien