Initializing and Onboarding

The SDKs must be initialized in the application.

Follow the steps below to initialize the SDKs.

  1. Initialize Kii Cloud SDK

  2. Initialize Thing-IF SDK (Including the owner and schema definition)

  3. Initialize Push Notification

  4. Execute Onboarding

Initializing the Kii Cloud SDK

Execute the following code when the web app starts. It is appropriate to execute it in the window.onload handler or the framework initialization handler in the HTML page.

  • // Initialize the Kii Cloud SDK. Call this method before any other Kii SDK API calls.
    kii.Kii.initializeWithSite("___APPID___", "___APPKEY___", kii.KiiSite.JP);
    
    // Initialize other components.
    ...
  • // Initialize the Kii Cloud SDK. Call this method before any other Kii SDK API calls.
    Kii.initializeWithSite("___APPID___", "___APPKEY___", KiiSite.JP);
    
    // Initialize other components.
    ...

Replace the placeholders ___APPID___ and ___APPKEY___ with your application's AppID and AppKey, respectively (See Creating a Kii Application for the details).

You can safely embed the AppID and AppKey in your application as long as you apply the correct access control. Read Security for more information.

Initializing the Thing-IF SDK

Next, initialize the Thing-IF SDK with the following sample code. You can execute the sample code at any time as long as the Kii Cloud SDK initialization in the previous step is done.

  • // Instantiate your application on Kii Cloud.
    const app = new ThingIF.App("___APPID___", "___APPKEY___", ThingIF.Site.JP);
    
    // Instantiate a Thing-IF API from the ThingIFAPIBuilder instance.
    const api = new ThingIF.ThingIFAPI(owner, accessToken, app);
  • // Instantiate your application on Kii Cloud.
    var app = new ThingIF.App("___APPID___", "___APPKEY___", ThingIF.Site.JP);
    
    // Instantiate a Thing-IF API from the ThingIFAPIBuilder instance.
    var api = new ThingIF.ThingIFAPI(owner, accessToken, app);
  • Replace the placeholders ___APPID___ and ___APPKEY___ with your application's AppID and AppKey, respectively (See Creating a Kii Application for the details).

    You can also initialize the SDK by specifying the base URL of the server https://api-jp.kii.com instead of the Site.

  • owner represents a user who will be the owner of the thing. accessToken represents the access token of the user. See Defining an Owner to learn how to get them.

    There are many ways to specify the user (owner). Which method to select depends on the design of the mobile app. In this guide, we will present a method with a pseudo user that does not require any explicit user registration and login. If you want to implement the explicit user login, you will need to provide a login screen and initialize the Thing-IF SDK after the login processes are done.

Keep the created ThingIFAPI instance available for subsequent processes by any manner such as retaining it in a class field. The initialized ThingIFAPI instance cannot be saved in the storage because the Thing-IF SDK for JavaScript does not have a method equivalent to loadFromStoredInstance for the other platforms.

Initializing the push notification feature

The web app receives responses from the thing via push notification, which is provided by MQTT over WebSocket.

Make MQTT.js available in advance by following the steps in Adding Push Notification.

Make the thing owner logged in by following the steps in Defining an Owner because the owner receives push notifications.

Call the APIs of the Kii Cloud SDK and MQTT.js as below after the owner logs in to establish an MQTT connection.

  • // Configure the push notification in production mode.
    const development = false;
    
    // Set up an MQTT endpoint for the logged-in user to Kii Cloud.
    kii.KiiUser.getCurrentUser().pushInstallation().installMqtt(development).then((response) => {
      const installationID = response.installationID;
      return kii.KiiUser.getCurrentUser().pushInstallation().getMqttEndpoint(installationID);
    }).then((response) => {
      const mqttTopic = response.mqttTopic;
    
      const endpoint =  "wss://" + response.host + ":" + response.portWSS + "/mqtt";
      const client = mqtt.connect(endpoint, {
        username: response.username,
        password: response.password,
        clientId: mqttTopic,
      });
    
      // Connect to the MQTT endpoint.
      client.on("connect", () => {
      console.log("Connected to MQTT server");
        client.subscribe(mqttTopic, () => {
          console.log("Subscribed to the MQTT topic");
        });
      });
    
      // Receive a push messsage.
      client.on("message", (topic, message, packet) => {
        if (topic === mqttTopic) {
          console.log("A message arrived");
        }
      });
    
      // Receive an error.
      client.on("error", (error) => {
        console.log("Error in MQTT: " + error);
      });
    }).catch((error) => {
      // Handle the error.
    
      // Get the installation ID for the failed getMqttEndpoint() method.
      const thePushInstallation = error.target;
    
      const errorString = error.message;
    });
  • // Configure the push notification in production mode.
    const development = false;
    
    // Set up an MQTT endpoint for the logged-in user to Kii Cloud.
    KiiUser.getCurrentUser().pushInstallation().installMqtt(development).then(
      function(response) {
        var installationID = response.installationID;
        return KiiUser.getCurrentUser().pushInstallation().getMqttEndpoint(installationID);
      }
    ).then(
      function(response) {
        var mqttTopic = response.mqttTopic;
    
        var endpoint =  "wss://" + response.host + ":" + response.portWSS + "/mqtt";
        var client = mqtt.connect(endpoint, {
          username: response.username,
          password: response.password,
          clientId: mqttTopic,
        });
    
        // Connect to the MQTT endpoint.
        client.on("connect", function() {
          console.log("Connected to MQTT server");
          client.subscribe(mqttTopic, function() {
            console.log("Subscribed to the MQTT topic");
          });
        });
    
        // Receive a push messsage.
        client.on("message", function(topic, message, packet) {
          if (topic === mqttTopic) {
            console.log("A message arrived");
          }
        });
    
        // Receive an error.
        client.on("error", function(error) {
          console.log("Error in MQTT:" + error);
        });
      }
    ).catch(
      function(error) {
        // Handle the error.
    
        // Get the installation ID for the failed getMqttEndpoint() method.
        var thePushInstallation = error.target;
    
        var errorString = error.message;
      }
    );

This is what is happening in the sample code:

  1. Get an MQTT endpoint

    Install an MQTT endpoint by calling pushInstallation().installMqtt() of the user who receives push notifications. The development argument of installMqtt() specifies whether the target network is a development environment or production environment. This argument makes no change for Thing Interaction Framework because push notifications for Thing Interaction Framework are sent to both the environments.

  2. Establish an MQTT connection with MQTT.js

    You can get the following information as response when you get an MQTT endpoint. mqtt.connect() connects to the MQTT broker with these parameters.

    Connection Parameter Value
    Hostname host property in the retrieved MQTT endpoint
    Port number portTCP property (for TCP) or portSSL property (for SSL/TLS) in the retrieved MQTT endpoint
    Port number for WebSocket portWS property (for TCP) or portWSS property (for SSL/TLS) in the retrieved MQTT endpoint
    Keep alive timer for the CONNECT command Specify this according to your app implementation (See Keep alive timer)
    Client identifier for the CONNECT command mqttTopic property in the retrieved MQTT endpoint
    Username for the CONNECT command username property in the retrieved MQTT endpoint
    Password for the CONNECT command password property in the retrieved MQTT endpoint
    Topic name for the SUBSCRIBE command mqttTopic property in the retrieved MQTT endpoint

    In general, use a connection over WebSocket with portWSS to connect from a web app in the browser. portTCP and portSSL do not support web browsers.

    Note that Kii Cloud only supports one MQTT connection per user. If multiple instances of a web app are launched at the same time, only one connection can be established.

    Some MQTT libraries repeatedly disconnect and reconnect a connection when multiple instances of a web app are launched at the same time. Implement logic to check the reconnection frequency and throw a connection error in the web app as required.
    Consider implementing a connection error for MQTT.js that also behaves this way.

  3. Set handlers for MQTT.js

    The sample code registers the following events as handlers for MQTT.js.

    • The connect event triggered when a connection is established. This event subscribes to the MQTT topic.
    • The message event triggered when a PUBLISH command arrives. See Getting Command Result to learn what process should be implemented within the handler.
    • The error event triggered when an MQTT error occurs.

    The MQTT.js events in the above sample code only call console.log(). Rewrite the events for your web app after confirming the behavior of the sample code.

    Ensure to check the MQTT topic name on receiving the PUBLISH command from the server because the PUBLISH command is used for various purposes. Also, ignore PUBLISH commands with unknown MQTT topic names for future enhancement.

    The MQTT topic name to be received for the Thing-IF SDK is the one subscribed by the SUBSCRIBE command in initialization.

Keep alive timer

MQTT defines a keep alive protocol to check if the connection is retained or disconnected.

The MQTT defines a keep alive protocol. The connection will be disconnected if the client does not send any message for the duration of 1.5 * the value of the keep alive timer set on the CONNECT request. If the client is not going to send any message within this duration, it needs to send the PINGREQ command.

The methods to implement the process to send the PINGREQ command varies depending on the libraries. Some libraries automatically send it internally, and other require the user program to handle it. See the documentation of your MQTT library to learn how to implement the process. MQTT.js automatically sends it internally and you do not need to add special handling.

Onboarding

To control a thing from a mobile app, you need to bind the application to the thing. This binding process is called Onboarding.

The onboarding can be made in one of the following two ways:

You will get the same result for both, but their flows are a bit different. Use the method that matches well with how your thing is to be implemented.

For the overview of the onboarding process, see Onboarding in the Function Guide.

You need to execute the onboarding before executing any ThingIFAPI method (other than onboarding). Any attempt to execute a method (e.g., executing a command and getting a thing state) without the onboarding will give you an error.

Onboarding from the mobile app

In this method, the mobile app will handle the most of the binding processes.

As explained in Onboarding in the Function Guide, in this method, only the mobile app will access Thing Interaction Framework to perform the onboarding. This will allow the implementation of the thing simple. You need, however, to establish a secure connection between the mobile app and the thing to share the result of the onboarding to the thing.

Step 1: Onboarding from the mobile app

First, the mobile app gets the thing's vendorThingID and thingPassword from the thing. This information is required for performing the onboarding.

Pass the information to the mobile app in any desirable way (See Thing identifier for more discussion).

The following sample code shows how you can onboard the thing from the mobile app.

  • // Set the thing credentials.
    const vendorThingID = "nbvadgjhcbn";
    const thingPassword = "123456";
    
    // Set onboarding options.
    const thingType = "AirConditioner";
    const properties = {};
    const interval = ThingIF.DataGroupingInterval.INTERVAL_15_MINUTES;
    const onboardRequest = new ThingIF.OnboardWithVendorThingIDRequest(vendorThingID, thingPassword, null, thingType, properties, null, interval);
    
    // Onboard the thing.
    api.onboardWithVendorThingID(onboardRequest).then((result: ThingIF.OnboardingResult) => {
      const thingID: string = result.thingID;
      const thingAccessToken: string = result.accessToken;
    }).catch((error: ThingIF.ThingIFError) => {
      // Handle the error.
    });
  • // Set the thing credentials.
    var vendorThingID = "nbvadgjhcbn";
    var thingPassword = "123456";
    
    // Set onboarding options.
    var thingType = "AirConditioner";
    var properties = {};
    var interval = ThingIF.DataGroupingInterval.INTERVAL_15_MINUTES;
    var onboardRequest = new ThingIF.OnboardWithVendorThingIDRequest(vendorThingID, thingPassword, null, thingType, properties, null, interval);
    
    // Onboard the thing.
    api.onboardWithVendorThingID(onboardRequest).then(
      function(result) {
        var thingID = result.thingID;
        var thingAccessToken = result.accessToken;
      }
    ).catch(
      function(error) {
        // Handle the error.
      }
    );

We are setting the following values.

  • vendorThingID: The ID of the thing that the thing vendor assigned. See here for more information. Any string with alphanumeric, hyphen, underscore and period up to 200 characters is accepted as long as it is unique in the application. This field value cannot be modified later.
  • thingPassword: The password of the thing. Basically, a unique password is assigned to each thing to secure the resources allocated for the thing in Thing Interaction Framework. You cannot change the password later.
  • thingType: The type of the thing. Any string with alphanumeric, hyphen, underscore and period up to 100 characters is accepted. Specify the same type that you've assigned in the schema.
  • properties: The properties of the thing in JSON format. These properties are useful when you use the Kii Cloud SDK together with the Thing-IF SDK. In this example, we are setting an empty JSON object.
  • interval: The grouping interval for storing state history. The history will not be stored if no grouping interval is specified. The available intervals are INTERVAL_1_MINUTE, INTERVAL_15_MINUTES, INTERVAL_30_MINUTES, INTERVAL_1_HOUR, and INTERVAL_12_HOURS defined in DataGroupingInterval. See Grouping and Sampling for more information.

This process returns the thingID and access token of the onboarded thing.

Note that once you onboard a thing, thingType, properties, and interval will be fixed on the device. An attempt to modify these values later will be ignored.

Note that the state history is not available until onboarding from the mobile app completes. The thing can upload state information but it is not stored as history data until the first mobile app gets associated with the thing.

Step 2: Initializing the thing

The mobile app needs to pass the result of the onboarding to the thing.

Onboarding with the above sample code returns the following two values from the function in the promise's then() to the mobile app.

  • thingID: thingID of the registered thing
  • thingAccessToken: Access token of the registered thing

Send these to the thing. Once the thing gets this information, it will execute the initialization (the thing will not access Thing Interaction Framework in this initialization). See here for the details.

The access token is the confidential information. Like a password, anyone who gets it will be able to control the thing. Use a secure method when you pass it to the thing.

Onboarding from both the thing and the mobile app

In this method, you first execute the onboarding request from a thing. Then, you execute the onboarding request from a mobile app.

You can actually start onboarding from either one of them. Both onboarding requests need to be processed, however, to start sending commands and getting thing state information.

As explained in Onboarding in the Function Guide, both the thing and mobile app will access Thing Interaction Framework while performing the onboarding in this method. The direct connection between the mobile app and thing, however, is not needed in this approach.

Step 1: Onboarding from the thing

Start onboarding from the thing. Once the onboarding is done, the thing will be able to report its state and receive commands.

See here for more details.

Step 2: Onboarding from the mobile app

Next, perform the onboarding from the mobile app. Once the onboarding is done, the mobile app will be able to send commands and get the thing state.

Here is the sample code:

  • // Set the thing credentials.
    const vendorThingID = "nbvadgjhcbn";
    const thingPassword = "123456";
    
    // Set the data grouping interval option.
    const interval = ThingIF.DataGroupingInterval.INTERVAL_15_MINUTES;
    const onboardRequest = new ThingIF.OnboardWithVendorThingIDRequest(vendorThingID, thingPassword, null, null, null, null, interval);
    
    // Onboard the thing.
    api.onboardWithVendorThingID(onboardRequest).then((result: ThingIF.OnboardingResult) => {
      const thingID: string = result.thingID;
      const thingAccessToken: string = result.accessToken;
    }).catch((error: ThingIF.ThingIFError) => {
      // Handle the error.
    });
  • // Set the thing credentials.
    var vendorThingID = "nbvadgjhcbn";
    var thingPassword = "123456";
    
    // Set the data grouping interval option.
    var interval = ThingIF.DataGroupingInterval.INTERVAL_15_MINUTES;
    var onboardRequest = new ThingIF.OnboardWithVendorThingIDRequest(vendorThingID, thingPassword, null, null, null, null, interval);
    
    // Onboard the thing.
    api.onboardWithVendorThingID(onboardRequest).then(
      function(result) {
        var thingID = result.thingID;
        var thingAccessToken = result.accessToken;
      }
    ).catch(
      function(error) {
        // Handle the error.
      }
    );

We are setting the following values in the sample code:

  • vendorThingID: The ID of the thing that the thing vendor assigned. See here for more information. Specify the vendorThingID you have set in Step 1.
  • thingPassword: The password of the thing. Basically, a unique password is assigned to each thing to secure the resources allocated for the thing in Thing Interaction Framework. Specify the password you have set in Step 1.
  • interval: The grouping interval for storing state history. The history will not be stored if no grouping interval is specified. The available intervals are INTERVAL_1_MINUTE, INTERVAL_15_MINUTES, INTERVAL_30_MINUTES, INTERVAL_1_HOUR, and INTERVAL_12_HOURS defined in DataGroupingInterval. See Grouping and Sampling for more information.

This process returns the thingID and access token of the onboarded thing.

Alternatively, the above API can use the thingID transferred from the thing (e.g., via Bluetooth) instead of using the vendorThingID.

Note that the state history is not available until onboarding from the mobile app completes. The thing can upload state information but it is not stored as history data until the first mobile app gets associated with the thing.