Searching...

Matching results

    Develop your application to communicate with AirVantage

    Objective

    This tutorial describes how to develop a Legato application to exchange data with AirVantage. The following use cases are covered:

    • Sending data such as sensor values from a Legato application to AirVantage
    • Sending commands or applying settings from AirVantage to a Legato application

    Data is transmitted over the standardized OMA LightWeight M2M protocol and secured with DTLS. This underlying protocol and security stacks are supported by the Legato framework. Therefore when developing Legato applications you only have to focus on gathering the data from the sensors and NO need to implement communication protocol and security stacks.

    Let’s develop a simple Legato application to illustrate this in 3 main steps:

    1. Develop a simple Legato application
    2. Upload the Legato application to AirVantage
    3. Run the application to exchange data between the device and AirVantage

    Prerequisite

    We recommend that you work through entirely the MangOH Getting Started Tutorial .

    Part references used in this tutorial

    Any issues ?

    If you encounter any issue to set up your device, don’t hesitate to use the developer forum to benefit from the developer community experience.

    Step 1: Develop and Install Application

    Let’s create our Legato application having the following capabilities:

    • Send application data variables to AirVantage
    • Receive application data settings from AirVantage

    This step starts defining a scenario to implement along with the data to be exchanged. It will then guide you through the code to manage the application data life cycle.

    Defining Application data

    Let’s design a simple home automation scenario to monitor and to control temperature of a Room, remotely using AirVantage.

    • In this model, a Room has 3 variables, they can be read (no write access) by AirVantage:
      • The name of the room
      • Current temperature of the room
      • Current state of the AC switch (on/off)
    • The Room has 1 setting, a target temperature, that can be set (read and write access) by AirVantage. User can remotely set the temperature of the room.
    • The Room also has 1 command, an AC switch, that can be triggered by AirVantage
    • In this remote control use case, the user can turn on the AC by defining a target temperature setting, the AC can then be turned off using this command.
    • The above variables, setting and command are gathered in an application data named Room, and declared as follow:
    assets:
    {
        Room =
        {
            variables:
            {
                string  Name
                float   Temperature
                bool    IsAC_on
            }
    
            settings:
            {
                int TargetTemperature
            }
    
            commands:
            {
                TurnOffAC
            }
        }
    }
    

    Embedded Application scenario

    Let’s monitor 2 rooms (a living room and a bedroom) in our application. To monitor 2 rooms, we need to create 2 instances of the Room data model, and for each instance:

    • assign a name to the room, in the field Name
    • set the current temperature of the room to variable TemperatureC
    • reflect the on/off state of the AC to variable IsAC_on
    • If the user remotely changes the target temperature TargetTemperatureC on AirVantage, then the AC will automatically be switched on
    • The user has the ability to remotely switch off the AC on AirVantage, by sending the TurnOffAc command

    Implementing the application

    • Download the source code from GitHub .
    • The Room data model, defined previousely, is declared in Component.cdef file
    • Before data exchange can occur with AirVantage, a LWM2M session must be established. Usually, this session is initiated by another application (e.g. a controler application managing the connectivity).
    • Legato AirVantage Data api (le_avdata.api) and Legato AirVantage Controler api (le_avc.api) are used to exchange data and to create LWM2M session. To be used in the application, these APIs must be declared as follow:

      • In the component definition file, Component.cdef :

        ...
        requires:
        {
            api:
            {
                le_avdata.api
                le_avc.api
            }
        }
        
      • In the application defition file, assetDataTutorial.adef:

        ...
        bindings:
        {
            assetDataTutorial.componentAssetData.le_avdata -> avcService.le_avdata
            assetDataTutorial.componentAssetData.le_avc -> avcService.le_avc
        }
        
      • In the Makefile, to include the path to AirVantage APIs:

        mkapp -v -t $@ \
              -i $(LEGATO_ROOT)/interfaces/airVantage \
              assetDataTutorial.adef
        
    • The main code handling the application data exchange with AirVantage is in assetDataMain.c

    For your reference, more detail on assetDataMain.c code

    • Variable and Setting declaration

      • Let’s declare the following as global:

            le_avdata_AssetInstanceRef_t    _assetInstRef[2];               //reference to the 2 asset instances
            char*                           _roomName[2];                   //array of 2 Variable Name
            float                           _currentTemperature[2];         //array of 2 Variable Temperature
            bool                            _isAcOn[2];                     //array of 2 Variable IsAC_on
            int                             _targetTemperature[2];          //array of 2 Setting TargetTemperature
            int                             _outsideTemperature = 30;       //assuming hot summer
            le_timer_Ref_t                  _tempUpdateTimerRef = NULL;     //reference to temperature update timer
            le_timer_Ref_t                  _avcTimerRef;                   //reference to the AVC session timer
            le_avc_StatusEventHandlerRef_t  _avcEventHandlerRef = NULL;     //reference to AirVantage Controller (AVC) Session handler
        
    • Application initialization

      • COMPONENT_INIT is called ONCE by Legato framework when the application starts. This function is the placeholder for initialization code.
      • This function must return to the framework. Application logic tasks shall be implemented outside of this function using event-handlers; event-driven model application.
      • Let’s do the following initializations in COMPONENT_INIT:

        • Register an AirVantage Controler (AVC) handler function, by calling le_avc_AddStatusEventHandler function, refer to Legato le_avc interface . This registration is required prior starting an AVC sesssion
        • Call le_avc interface (le_avc_StartSession) to start an AVC Session with AirVantage

          _avcEventHandlerRef = le_avc_AddStatusEventHandler(AVsessionHandler, NULL);    //register a AVC handler
          le_result_t result = le_avc_StartSession();      //Start AVC session. Note: AVC handler must be registered prior starting a session
          if (LE_FAULT == result)
          {
              le_avc_StopSession();
              le_avc_StartSession();
          }
          
        • Create a timer to close the AVC session and exit application, in 10 min

          _avcTimerRef = le_timer_Create("assetDataAppSessionTimer");     //create timer
          le_clk_Time_t    delay = { 600, 0 };                            //allow this app to run for 10 min
          le_timer_SetInterval(_avcTimerRef, delay);
          le_timer_SetRepeat(_avcTimerRef, 1);                            //set repeat to once
          //set callback function to handle timer expiration event
          le_timer_SetHandler(_avcTimerRef, timerExpiredHandler);
          //start timer
          le_timer_Start(_avcTimerRef);
          
        • Create 2 instances of Room Asset, by calling le_avdata_Create, refer to Legato le_avdata interface

          _assetInstRef[0] = le_avdata_Create("Room"); //create instance #1 for asset "Room"
          _assetInstRef[1] = le_avdata_Create("Room"); //create instance #2 for asset "Room"
          
        • Assign default values to our 2 instances of Room asset (declared as global variables)

          int i = 0;
          //Assign default value to asset data fields
          _roomName[i] = (char *) malloc(16);
          strcpy(_roomName[i], "bedroom");
          _currentTemperature[i] = 31.0;
          _isAcOn[i] = false;
          _targetTemperature[i] = 19;
          i++;
          _roomName[i] = (char *) malloc(16);
          strcpy(_roomName[i], "living-room");
          _currentTemperature[i] = 30.0;
          _isAcOn[i] = false;
          _targetTemperature[i] = 19;
          
        • Map the data value to instances

          for (i=0; i< 2; i++)
          {
              le_avdata_SetString(_assetInstRef[i], "Name", _roomName[i]);
              le_avdata_SetInt(_assetInstRef[i], "Temperature", _currentTemperature[i]);
              le_avdata_SetBool(_assetInstRef[i], "IsAC_on", _isAcOn[i]);
              le_avdata_SetInt(_assetInstRef[i], "TargetTemperature", _targetTemperature[i]);
          }
          
        • Register handler, in order to apply Settings and Commands sent by AirVantage. For each data field (settings and commands), call Legato API (le_avdata_AddFieldEventHandler) to register handler functions that will be called by the framework whenever the field is altered by AirVantage.

          for (i=0; i< 2; i++)
          {
              // call OnWriteSetting() handler whenever the setting "TargetTemperature" is accessed
              le_avdata_AddFieldEventHandler(_assetInstRef[i], "TargetTemperature", OnWriteSetting, NULL);
              // call OnCommand() handler whenever the setting "TurnOffAC" is accessed
              le_avdata_AddFieldEventHandler(_assetInstRef[i], "TurnOffAC", OnCommand, NULL);
          }
          
        • Simulate the rooms temperature, let’s set a timer to update the temperature every 5 seconds

          _tempUpdateTimerRef = le_timer_Create("tempUpdateTimer");     //create timer
          le_clk_Time_t      interval = { 5, 0 };                       //update temperature every 5 seconds
          le_timer_SetInterval(_tempUpdateTimerRef, interval);
          le_timer_SetRepeat(_tempUpdateTimerRef, 0);                   //set repeat to always
          le_timer_SetHandler(_tempUpdateTimerRef, updateTemperature);  //call updateTemperature function every 5 seconds
          le_timer_Start(_tempUpdateTimerRef);
          
    • Setting Handler functions

      • Our application needs to implement handler function to retrieve the value of a Setting (TargetTemperature) set by AirVantage.
      • This function should have the prototype defined by le_avdata_FieldHandlerFunc_t, refer to le_avdata interface
      • This function shall be registered in COMPONENT_INIT with le_avdata_AddFieldEventHandler
      • Let’s name it OnWriteVariable:

        • void OnWriteVariable(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
        • This function will be called by the framework whenever AirVantage wants to change the fieldname Setting of our asset instance, referenced by instRef
        • To retrieve the Setting value pushed by AirVantage, call le_avdata_GetString, le_avdata_GetInt or le_avdata_GetBool

          void OnWriteSetting(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
          {
              int i;
              for (i=0; i<2; i++)
              {
                  if (instRef == _assetInstRef[i])
                  {
                      if (strcmp(fieldName, "TargetTemperature") == 0)
                      {
                          int  nTemp;
                          le_avdata_GetInt(instRef, fieldName, &nTemp);                       //Get the new setting from AirVantage
                          if (nTemp != _targetTemperature[i])
                          {
                              _isAcOn[i] = true; //let's set the AC status to ON
                              le_avdata_SetBool(instRef, "IsAC_on", _isAcOn[i]);              //reflect the new value to instance
                              _targetTemperature[i] = nTemp;
                              le_avdata_SetInt(instRef, fieldName, _targetTemperature[i]);    //reflect the new value to instance
                          }
                      }
                      break;
                  }
              }
          }
          
    • Command Handler functions

      • Our application needs to implement handler function to Execute the Command (TurnOffAC) set by AirVantage.
      • This function should have the prototype defined by le_avdata_FieldHandlerFunc_t, refer to le_avdata interface
      • This function shall be registered in COMPONENT_INIT with le_avdata_AddFieldEventHandler
      • Let’s name it OnCommand:

        • void OnCommand(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
        • This function will be called by the framework whenever AirVantage wants to execute the TurnOffAC Command on our asset instance, referenced by instRef

          void OnCommand(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
          {
              int i;
              for (i=0; i<2; i++)
              {
                  if (instRef == _assetInstRef[i])
                  {
                      if (strcmp(fieldName, "TurnOffAC") == 0)
                      {
                          _isAcOn[i] = false;                                 //Execute the commande, just turn AC status to OFF
                          le_avdata_SetBool(instRef, "IsAC_on", _isAcOn[i]);  //reflect the new value to instance
                      }
                      break;
                  }
              }
          }
          
    • Simulate temperature

      • The handler updateTemperature is called by the framwork every 5 seconds, as set in COMPONENT_INIT
      • This function modifies the temperature as follow:
        • if AC switch is OFF, then converge the room temperature to the outside temperature
        • if AC switch is ON, then converge the room temperature to the targetTemperature (set in AirVantage)
      • Simulated room temperatures are then pushed to AirVantage by calling Legato API le_avdata_SetFloat. This is performed automatically by the underlying LWM2M Observe feature when AVC session is opened.
    • AVC Handler function

      • AVC handler function, AVsessionHandler, has been registered in the COMPONENT_INIT function, this is required to start an AVC session with AirVantage
      • For this tutorial, let’s do nothing in this function
    • Exit Application

      • The handler timerExpiredHandler is called by the framwork 10min later, as set in COMPONENT_INIT
      • This function Close LWM2M session and Quit the application

    Compiling & Installing the application on the target device

    • Compile the source code from assetDataTutorial main folder and install the application on target
    • In this tutorial, we are targeting mangOH board embedding a WP8548 module, therefore the compiler target is wp85 in guidelines hereafter. Depending on the target module, you’d need to use a different compiler target (e.g. ar7, wp7 or ar86).
    • Enter these 2 commands on the Host, in Termimal #1:

      make wp85
          Upon the make, a <software package> should be generated:
              <software package> is *assetDataTutorial.wp85.update*
      
      
      instapp <software package> <device_ip_address>
          This command will upload the <software package> to the device
      

    In Step 1, we’ve covered the following:

    1. Define the application data model and the different type of data: Variables, Settings and Commands
    2. Source code provided in GitHub
    3. Requirements to use Legato AirVantage APIs
    4. Compile our sample Legato application for MangOH/WP85xx
    5. Install the Legato application onto MangOH/WP85xx

    Step 2: Upload App to AirVantage

    In the previous step, we have developed the application and installed it on the target device.

    In this step, let’s upload our application and data model to AirVantage. The “Room” data model declared in Component.cdef (refer to step1) is defined in a manifest file (XML file generated automatically at compile time). AirVantage needs to have this manifest information to gain awareness of “Room” data model in order to exchange predefined data with our device application.

    Create an update package & Generate package for upload to AirVantage

    This step shall be performed on the Host, in Termimal #1:

    av-pack -f assetDataTutorial.wp85.update <TypeName>
        where <TypeName> shall be globally unique (e.g. assetTutorialAppV3),
        AirVantage uses it to uniquely identify multiple versions of our application
    

    Upload Application package to AirVantage

    • Log into AirVantage portal
    • Click on the “Develop” activity then click on My Apps
    • Click on the Release button
    • Select the application package zip file assetDataTutorial.zip, created in the previous section
    • Check the “I want to publish my application after releasing it” checkbox in the Advanced settings option
    • Finally, click on Start

    Assign our application to device on AirVantage

    • Before our device can exchange “Room” data fields with AirVantage, the uploaded application must be assigned to our device on AirVantage
    • Log into AirVantage portal, go to Inventory activity then Systems
    • Select your system by clicking on its Name
    • Click on the Edit icon
    • In the Applications field, type in the name of the application (i.e. assetDataTutorial) and select it
    • Click on Save button

    You can now use this package to install your application remotely using AirVantage.

    In Step 2, we’ve covered how to:

    1. Create an application update package for a target device
    2. Generate application package for upload to AirVantage, application package comprise the update package and data model
    3. Upload application package to AirVantage
    4. Assign application to our device on AirVantage

    Step 3: Data Exchange

    In step #1, we have created an application that can exchange a collection of information (application data fields) with AirVantage. In step #2, we have packaged the application along with a manifest file then uploaded it to AirVantage. The manifest file exposes application data collection information to AirVantage.

    In this step, we are going to retrieve the current values, i.e. name of the room, current temperature, target temperature and the AC switch state for bedroom and the living room on AirVantage.

    Launch application & View application log

    We are now ready to start data exchange with AirVantage, let’s start the application and get ready to view the log:

    • In the Terminal #2:
      • Connect to the target using ssh: ssh root@device_ipAddr
      • Launch logread -f | grep “Legato AssetData” to continuously view the log
    • In the Terminal #3:
      • Connect to the target using ssh: ssh root@device_ipAddr
      • Type in “app status” command to make sure that assetDataTutorial is listed
      • Launch the application: “app start assetDataTutorial”
    • Note the data exchange log in the Terminal #2 (using logread -f)

    Communication with AirVantage

    The default behavior of LightWeight M2M protocol consists in initiating a communication to the server by the device. Once there is a connection between the server and the device, the server can send any request to the device: read or write a data, execute a command, apply a firmware upgrade, install an application, …

    When a device is on the field:

    • At first boot, it starts to communicate with the bootstrap server to collect credentials and AirVantage url. It will do this communication, only if AirVantage deny the connection or at regular period to change the security keys (step 1 and 2)
    • Then the device initiates a communication with AirVantage, updates the objects list (step 3)
    • AirVantage sends the pending requests to the device (step 4)
    • The device executes the requests
    • The device communicates the acknowledgements and close the connection
    If the use case requires to collect data as soon as the device is ready to communicate to AirVantage and at high frequency, this behaviour doesn’t fit this use case.

    AirVantage supports a feature called LWM2M Observe to fit this use case.

    Pushing the data to AirVantage

    We want to use the Observe mechanism in order to send new data values on the fly:

    • At first communication with a device, AirVantage will request to observe a list of data (step 1). That means to be notified when there is any new values for this list of data.
    • When a new value is get from the sensor, the value is pushed to legato (step 2).
    • The device will send the applicative data automatically without any new request from AirVantage (step 3).

    The observed objects are the following:

    • 4: Connectivity
    • 5: Firmware
    • 9: Applications Package information
    • le_xxxx/ > 1000: Applicative data

    During the sample application updates data in Legato, you can see the new values directly updated in AirVantage, for example using the timeline view.


    You can go to the next tutorial to discover:

    1. How to create a dataset that specifies the device data to be read by AirVantage
    2. How to retrieve data from device
    3. How to apply new setting to device
    4. How to send command to device

    More features you may be interrested:

    TOP