AirVantage Data API
API Reference
How To Manage Data
This API provides a data service to allow Apps to manage App-specific data on the AirVantage server.
IPC Interfaces Binding
All the functions of this API are provided by the avcService platform service.
Code sample for binding to avcService:
bindings: { clientExe.clientComponent.le_avdata -> avcService.le_avdata }
AirVantage Data Overview
Data is setup as Assets -- a collection of fields that can be managed by the AirVantage server.
An asset field is a single data point taken from a sensor that can be managed by the AirVantage server.
A field can be:
- variable allowing the AirVantage server to read the value, and can be read/writtten to by an App.
- setting allowing the AirVantage server to read/write the value, and can be read/written to by an App.
- command allowing the AirVantage server to invoke a function in the App.
Fields are referred to by paths and need to follow these rules:
- A parent path can't contain a field, parent path or child path that has the same name.
- Paths must be separated by a slash ("/") or a dot (".").
- When using a ("/") the path must start with a ("/") (e.g., /a/b/c)
- When using a (".") the path must start with the first field, (e.g., a.b.c)
- Note
- There is no leading "." when using "." delimiter.
Variable and setting fields also have types. The available field types are:
- string
- integer
- float
- boolean
Variable and setting fields have no default values. When they are first created with the le_avdata_CreateResource() , all values are "null". They can also be set to "null" values with the le_avdata_SetNull() .
Fields do not have a fixed data type, so any of the SetInt/Float/Bool/String can be called for a certain field to change its value and its type. However, A GetInt/Float/Bool/String API must be called on a field with the matching type. In other words, a Get API does not perform type-casting.
- Note
- If a user enters a value 0 for float data type, an error will be returned (LE_NOT_FOUND), as the system infers 0 as an integer value and the data type doesn't match. 0.0 needs to be set for the float data type to be zero.
Field Values and Activity
Set functions are available to set field values (including "null"). Get functions are available to get field values.
An App can register a handler so that it can be called when an activity occurs on a field. This is optional for variable and setting fields, but is required for command fields. Registered handlers are called only when activities from AV server occurs. Client activities do not trigger handlers.
A handler registered with a command field is invoked with an optional argument list sent from the AirVantage server. The APIs GetInt/Float/Bool/StringArg and le_avdata_GetStringArgLength() are available to extract the arguments in the handler definition. AV server does not send argument lists for handlers registered with variable and setting fields.
A handler registered with a command field must call the le_avdata_ReplyExecResult() at the end of its definition, in order to reply the command execution result to the AV server.
Sometimes instead of waiting for activity to occur on a field, users may want to have their application notify the server of their asset data details. Asset data can also be pushed from the device to the server by using le_avdata_Push().
This code sample shows how to push asset data to the server (assuming session is opened)
static void PushCallbackHandler(le_avdata_PushStatus_t status,void* contextPtr){if (status == LE_AVDATA_PUSH_SUCCESS){// data pushed successfully}}{le_result_t result;if (result != LE_OK){LE_FATAL("Error in creating livingRoom resource.");}if (result != LE_OK){LE_FATAL("Failed to set value for livingRoom resource.");}le_avdata_Push("/livingRoom/sensor1", PushCallbackHandler, NULL);}
If users simply want to push a data dump to the server without creating resources, le_avdata_PushStream() is available.
- Note
- The push stream API has a limit of 20K.
{int fd = open("data.txt", O_RDONLY);if (fd == -1){LE_FATAL("Failed to open file.");}// The data dump sent to the server will be display under <Path>le_avdata_PushStream("<Path>", fd, PushCallbackHandler, NULL);}
Namespace
By default all asset data paths are created and managed under the application namespace. Calling le_avdata_GetXXX
/ le_avdata_SetXXX/
le_avdata_AddResourceEventHandler() / le_avdata_Push() with the path "/a/b/c" will search for the "/a/b/c" data under the apps namespace. In order to query any paths created under an application namespace, user must append the app name in front of the request on the server side. If creating asset data under application namespace is not desired, users must call le_avdata_SetNamespace() and set the value to global. An application that changes its namespace to global will be creating asset data in the global space. All asset data API will use the last namespace set until the function is called again and the namespace is set to something new.
- Note
- All asset data paths created by the application are deleted when it is stopped, even the asset data created under global namespace. No asset data can therefore be persistent after an application restart, regardless of the namespace used to create it.
Example:
#define RESOURCE_A "/test/resourceA"{int intVal;LE_ASSERT(le_avdata_SetInt(RESOURCE_A, 1) == LE_OK);LE_ASSERT(le_avdata_GetInt(RESOURCE_A, &intVal) == LE_OK);LE_ASSERT(intVal == 1); // value obtained under the application namespace// Switch to global namespaceLE_ASSERT(le_avdata_SetNamespace(LE_AVDATA_NAMESPACE_GLOBAL) == LE_OK);LE_ASSERT(le_avdata_SetInt(RESOURCE_A, 2) == LE_OK);LE_ASSERT(le_avdata_GetInt(RESOURCE_A, &intVal) == LE_OK);LE_ASSERT(intVal == 2); // value obtained under the global namespace}
An application starts by creating a path "/test/resourceA" under the default application namespace and sets it to 1. Then it sets the namespace to global and creates another path "/test/resourceA" with a value of 2. A read request from the server on "<appName>/test/resourceA" will return 1; whereas a read request on "/test/resourceA" will return 2.
Time Series
This feature enables user Apps to collect and keep in memory data when the device is off-line and send the data to the AirVantage Server when the device is on-line.
Time series records can be initialized using le_avdata_CreateRecord(). Data can be accumulated using the following data types along with a specified time stamp (milliseconds elapsed since epoch).
User apps can then open an avms
session, and push the collected history data using le_avdata_PushRecord(). The callback used when calling le_avdata_PushRecord() will indicate whether the push has been successful or not.
This code sample shows how to collect data and send to the server (assuming session is opened)
static void PushCallbackHandler(le_avdata_PushStatus_t status,void* contextPtr){if (status == LE_AVDATA_PUSH_SUCCESS){// data pushed successfully}}static void SendData(){struct timeval tv;uint64_t utcMilliSec;le_result_t result;le_avdata_RecordRef_t recRef = le_avdata_CreateRecord();gettimeofday(&tv, NULL);utcMilliSec = (uint64_t)(tv.tv_sec) * 1000 + (uint64_t)(tv.tv_usec) / 1000; // get current timeresult = le_avdata_RecordFloat(recRef, "speed", 0.08, utcMilliSec);if (result == LE_OK){le_avdata_PushRecord(recRef, PushCallbackHandler, NULL);}le_avdata_DeleteRecord(recRef);}
User App Session Management
An App can request to open a session and register a handler to get notified of a session events. le_avdata_RequestSession() and le_avdata_ReleaseSession() can be used to open a session and close a session respectively. If the session was initiated by an user app, the session will be closed when all apps release their session reference. le_avdata_AddSessionStateHandler() and le_avdata_RemoveSessionStateHandler() can be used to add and remove notification handlers.
Fatal Behavior
An invalid asset name or field name is treated as a fatal error (i.e. non-recoverable) and will result in the client App being terminated.
Copyright (C) Sierra Wireless Inc.