Return Updated Device Cloud Properties as Commands

When pushing data to the cloud, there is an opportunity to use Octave's Cloud Action Runner HTTP.Get capabilities to check if the device's properties are available in the third-party cloud, in order to return them to the device as commands if they have changed.

1855

📘

Key Takeways

  • Along with HTTP POST requests to a third-party cloud, Cloud Actions can invoke HTTP GET requests to retrieve information.
  • Streams can be used to store data on the cloud side, and the hash key field can be used to store one unique Event for a given key (a device ID in this use case).
  • Before using dedicated Streams in a Cloud Action, you need to create them through the Octave UI or via the Octave API.
  • This applies for an approach where you want Octave to check the latest device properties when data is to be posted to the Cloud. For a pure cloud-to-device property/command push, the recommended approach is for your cloud service to invoke the Octave REST API Reference.

The following is an example Cloud Action that handles this implementation:

function(event) {

  var returns = {};
  // Retrieve device ID
  var deviceId = event.path.split("/")[3];
  var path = event.path;



    // Call Cloud to retrieve device properties

    var properties_url = 'https://mycloud/devices/' + deviceId + '/properties';

    var properties_data = Octave.Http.get(properties_url);

    var get_device_properties = JSON.parse(properties_data.content);



    // check last known device properties stored in Octave /iotcentral/properties stream
    var filter_string = "hash=='" + String(deviceId) + "'";

    var get_last_properties = Octave.Event.findOne('properties_streamId', {
      filter: String(filter_string)
    });





    if (get_last_properties != null) {
      // set last known properties to the retrieved values

      var last_properties = get_last_properties.elems;
     
    } else {
      // if no properties exist yet, initialize them with default values
      console.log("device has no properties");
      
      var last_properties = {
        "propertyA": valueA,
        "propertyB": valueB
      };
      returns["/mycompany/properties"] = [{
        "elems": last_properties,
        "hash": deviceId
      }];
    }



    // Construct the data payload to send to cloud



    var Payload = {
      "device": {
        "deviceId": deviceId
      },
      "measurements": event.elems
    };


    var postBody = JSON.stringify(Payload);

    // Construct the request Header
    var postHeaders = {
      'Content-Type': 'application/json'
    };


    var result = Octave.Http.post('https://mycloud/device/', postHeaders, postBody);

    var command_stream = "/mycompany/devices/" + deviceId + "/:command";



    // Send properties to the device command stream if properties have changed:

    if (last_properties != device_properties) {
      // save device properties to a Octave.Event.find(streamId, { filter: "" })
      returns["/mycompany/properties"] = [{
        "elems": device_properties,
        "hash": deviceId
      }];

      returns[command_stream] = [{
        "elems": {
          "virtual": {
            "propertyA": {
              "value": device_properties.propertyA},
            "propertyB": {
              "value": device_properties.propertyB},
          }
        }
      }]
    }

    return returns;
}