Return updated device Cloud properties as Commands

When pushing data to the cloud, the opportunity can be taken to check the device properties if they are available through an API call in order to return them to the device as commands if ever they have changed.

📘

Key Takeways

  • along with HTTP POST to a 3rd party cloud, Cloud Actions can make HTTP GET to retrieve information
  • Streams can be used to store data on the Cloud side, and the hash key can be used to store one unique Event for a given key (device id in this use case)
  • before using dedicated Streams in a Cloud Action, you need to create them through Octave UI or Octave API
  • obviously 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 pure Cloud to device property/command push, the recommended approach is for your Cloud to call the Octave API.
1855

Here's an example Cloud Action handling this implementation:

function(event) {

  var returns = {};
  // Retrieve device ID
  var deviceId = event.Tags.Name;
  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;
}