Disruptive Technologies Disruptive Developers

Sensor Identification From Custom Installation App

Introduction

The sensors do not have printed identifiers on them.

As part of installation it is a common need to identify the actual sensor being installed and provide it with a name and identity that will be used when processing data from it.

This can be performed using Studio via the “Identify Sensor” feature.

This article describes the recommended approach to identify sensors during installation using the API.

Performing installation

When sensors are shipped they will arrive in packages marked with kit codes, such as “work-building-flower”. All sensors in the packages are labelled with this kit. Through the API it is possible to listen to events limited to this set of sensors.

During installation, the installer will presumably have an application that allows him to register the installation location into the domain system used. The additional required information is getting the ID of the sensor itself to store with the location info.

As part of the installation flow, the user identify a sensor simply by touching it.

Technical implementation overview

We assume that the installation is performed on a mobile device talking to an installation server. Both client and server is assumed to be part of a domain system that manage sensor installation locations and identities.

Installation Server

The server will talk to the Disruptive cloud via our APIs and use its own domain specific databases to connect information such as location information with specific sensors.

A service account for the server should be setup to be used for API access. See the Service Account article for more information about creating a service account.

The service account is given Org. Admin rights enabling it to perform such operations as moving sensors between projects.

A separate service account should be setup for the mobile client access. This account should only be granted read-only access to required projects.

Installation Mobile Client Application

The installation client will log into the server using the domain system authentication user management. No Disruptive accounts are involved in this.

When the client needs to access the Disruptive API for sensor identification, it will request an access token from the server. The server will fetch a new token from Disruptive’s cloud and provide this to the client for a time limited access to the API. The token should be fetched for the service account setup to be used from the client.

Technical implementation example details

The example below shows how to use the API to listen for a first touch of a sensor among a set of candidates. When the sensor has been found, it will be listened to for an additional confirmation touch.

Sensor identification

The API allows listening to a stream of events from sensors in a single project, filtered by label values.

With a small set of sensors to decide amongst, the challenge of figuring out which sensor is touched drops down to the trivial case of just listening for the first touch event received.

Sensors are shipped in boxes with a limited number of devices and a kit label clearly marked on the box.

Using this label as an example, the JavaScript code for the identification would look something like:


// The URL for the version of the API to use :
let api_root = "https://api.disruptive-technologies.com/v2"

/**
 *  Global variables in this example code.  In a real UI these will be
 *  fetched from the server as part of the setup before the UI was activated
 */

// The token is a temporary access token passed to the installation client from
// the domain system server.  The server requested the access token for a
// service account which is setup with read-only (Role=User) access to the inventory project: */
let token="<temp-access-token-fetched-from-server>"
// The project Id can be copied from the project-detail page i Studio:
let inventory_project_id="<the project id of the inventory project for the org>"
// This is the label on the box:
let kit_label="<the kit label on the box with the sensors>"

/* ========================================================================
 *  Demo sequence.  Listen for a touch event and output the sensor found.  
 *  Then listen to that sensor and verify the match with a second touch
 * ======================================================================== */
firstTouched()
  .then(deviceName => {
    console.log("First sensor touched : " + deviceName);
    console.log("Touch sensor again to confirm that we have the right one");
    return deviceName;
  })
  .then(confirmFoundSensor)
  .then(target => {
    console.log(target, "was touched again");
  })
  .catch(e=>{
    console.error(e);
  });



/**
 * Helper method that returns a promise that will be fulfilled when one of the
 * sensors in the inventory package, labeled with the kit_label, is touched.
 */
function firstTouched() {
  return new Promise((resolve, reject) => {
    // Constructing the right api request
    let label_filter_param =
      "label_filters=" + encodeURIComponent("kit=" + kit_label);
    let event_filter_param = "event_types=touch";
    // The server side event API in browsers does not allow custom headers to be
    // set, thus we pass in the auth token as a parameter
    let token_param = "token=" + token;
    let sensor_events_api =
      api_root + "/projects/" + inventory_project_id + "/devices:stream" +
      "?" + label_filter_param +
      "&" + event_filter_param +
      "&" + token_param;
    let es = new EventSource(sensor_events_api);
    es.onmessage = function(msg) {
      let stream_event = JSON.parse(msg.data);
      if (stream_event.result) {
        let device_event = stream_event.result.event;
        resolve(device_event.targetName);
      } else {
        reject(stream_event);
      }
      es.close();
    };
    es.onerror = function(e) {
      reject(e);
      es.close();
    };
  });
}


/**
 * Helper function to demo that after we have found a sensor, we can
 * establish a listener for events from that sensor and show touch events
 * in the UI.  This allows the user to verify that he has found the right
 * sensor.  In a real UI this could be kept active until the user closes the
 * page.  Here we just wait for one additional touch or time out after 5 seconds
 */
function confirmFoundSensor(deviceName) {
  return new Promise((resolve, reject) => {
    // Constructing the right api request
    let token_param = "token=" + token;
    let event_filter_param = "event_types=touch";
    let sensor_events_api = api_root + "/" + deviceName + ":stream" +
      "?" + event_filter_param +
      "&" + token_param;
    let es = new EventSource(sensor_events_api);
    es.onmessage = function(msg) {
      let stream_event = JSON.parse(msg.data);
      if (stream_event.result) {
        let device_event = stream_event.result.event;
        resolve(device_event.targetName);
      } else {
        reject(stream_event);
      }
      es.close();
    };
    es.onerror = function(e) {
      reject(e);
      es.close();
    };
    setTimeout(()=>{
      reject("Sensor not touched again in 5 seconds, giving up.")
      es.close();
    },5000);
  });
}

In this example we used an access token. See the authentication article for description of how the server used the key and secret for a service account to request that token. How the client requested the token from the server will depend on the implementation choices for the mobile client overall, and is not discussed in this article.

Variations of this approach

Other possible approaches for limiting sensor selection candidates during installation :

  • Having individual projects for each installer or e.g. installation car. Sensors should be moved into these ready-to-install projects as they are signed out from central of local warehouse.
  • Sensors could be moved into client project as part of planning process and tagged with a work flow code, e.g. setting a label “installation-status=assigned”.

As long as it is possible to reduce the number of sensors down to a set where it is highly unlikely that several will be touched at the same time, the approach above should suffice.

Post identification

When the mobile client has identified the sensor id, it should notify the server which should perform the following:

  • Remove the sensor from the set listened to by the identify sensor feature. This will most likely mean moving it from the inventory project and into the correct project for the installation. Possibly also by removing or updating labels used to flag the installation work status.
  • Label the sensor with relevant meta data, such as locationId from the domain system, and/or by e.g. the domain system device id assigned to the sensor.

Moving sensors from inventory to client project

The server needs to use the API via a service account that is either setup with admin rights to both the inventory project and the project for the current client installation, or as org-admin for the customer in total.

See API reference doc for moving sensors between projects with the “transfer” method.

Updating label information for the sensor

See API reference doc for adding, updating and removing labels from sensors.