Module airvantage.asset

Racon Application Services object used to send data to the M2M Application Services server.

Instances of this object should be created through airvantage#airvantage.newAsset.

This module relies on an internal background service known as the Mihini Agent, which is responsible for queuing data, managing the flush timers and sending the data to the remote M2M server. Many of the APIs in this module relay the data to the Agent; the Agent then manages the data as described.

For information regarding supported policies, see the airvantage#airvantage module documentation.

Two methods are supported for sending data to the M2M servers:

  1. pushData: this is a simple API for managing how to send data, this is the recommended method for most use cases.
  2. Tables (via newTable): this allows for more advanced control of the transfer of data; it is an experimental API.

Moreover, methods setUpdateHook and sendUpdateResult are provided to let application handle software update requests from the M2M servers in a custom way.

Type asset

asset:close()

Closes an #asset instance.

asset:newTable(path, columns, storage, sendPolicy, purge)

Creates and returns a airvantage.table#table instance.

asset:pushData(path, data, sendpolicy)

Pushes some unstructured data to the agent.

asset:sendUpdateResult(componentName, updateResult)

Sends the result of the software update request previously received by an asset.

asset:setUpdateHook(hook)

Changes the hook function to be called when the asset receives a software update request from the portal.

asset:start()

Starts a newly created #asset.

asset.tree

airvantage.asset data tree

An #asset contains a data tree, in its field tree.

Type airvantage.asset

Type asset

Field(s)

asset:close()

Closes an #asset instance.

Once this destructor method has been called, no more message can be sent nor received by the instance, and the resources it reserved can be reclaimed, either immediately or through the garbage collection cycle.

Return value

"ok" on success.

asset:newTable(path, columns, storage, sendPolicy, purge)

Creates and returns a airvantage.table#table instance.

Parameters

  • path : (relative to the asset's root) where the data will be sent.

  • columns : list of either airvantage.table#columnspec or column names (to use default values).

  • storage : either string "file" or "ram"; how the table must be persisted.

  • sendPolicy : name of the policy controlling when the table content is sent to the server.

  • purge : boolean indicating whether an existing table, if any, must be recreated (true) or reused (false/nil). Recreation means the table will be dropped then recreated from scratch (so any data inside table will be lost).

Return values

  1. an airvantage.table#table to store and consolidate structured data.

  2. nil + error message otherwise.

asset:pushData(path, data, sendpolicy)

Pushes some unstructured data to the agent.

Those data are not necessarily moved forward from the agent to the server immediately: agent-to-server data transfers are managed through policies, as described in the Racon technical article.

This API is optimized for ease of use: it will internally try to reformat data in the most sensible, server-compatible way. Applications requiring a tight control over how data are structured, buffered, consolidated and reported should consider the more advanced asset.newTable API.

Data sent through pushData can be a flat set of key/values in a record, or can contain nested sub-records. It can also be a simple value out of a record, if the path is not empty: in this case, the last path segment will be used as a datastore key. You also can add a timestamps in the record to inform to the server side about the sending date.

--Examples
asset :pushData('foo', {x=1, y=2}) -- sends <assetroot>.foo.x=1, <assetroot>.foo.y=2
asset :pushData('foo.x', 1, 'midnight') -- sends <assetroot>.foo.x=1 according to the "midnight" policy
asset :pushData('foo', { timestamp=os.time(), y={a=2, b=3}}) -- sends <assetroot>.foo.y.a=2 and <assetroot>.foo.y.b=3 with the timestamp

Note: Notice that for the server, all data is timestamped. If there is no 'timestamp' or 'timestamps' entry on a record, it will be timestamped at the date of its reception by the server (see more detail in Racon Lua library article). Please note that if several values of the same variable are pushed without timestamp in the same communication with the server, then the server might not be able to distinguish each record and might only keep one of them. As a result, sending a record without timestamp is totally legitimate, but needs to be done knowing previous remarks.

Parameters

  • path : the datastore path under which data will be stored relative to the asset node (optional).

  • data : a table of key/value pairs, or a simple non-table serializable value.

  • sendpolicy : name of the policy controlling when the data must be sent to the server, if omitted then the default policy is used.

Return values

  1. "ok" on success.

  2. nil followed by an error message otherwise.

asset:sendUpdateResult(componentName, updateResult)

Sends the result of the software update request previously received by an asset.

Parameters

  • componentName : a string, this must be the same value as the one that was given as argument to the update hook (the hook registered with airvantage.asset#asset.setUpdateHook).
    As only one software update is possible for the same component at the same time, the couple asset+componentName fully identifies the software update request.

  • updateResult : a number, the result of the update, 200 for success, any other value means error.
    Values from 480 to 499 are reserved for applicative error codes, so it is highly recommended to use one (or more) of those to signify an error coming from an asset update.

Return values

  1. "ok" on success

  2. nil + error message otherwise.

asset:setUpdateHook(hook)

Changes the hook function to be called when the asset receives a software update request from the portal.

Notes:

  • There can be only one pending SoftwareUpdate request at a time.
  • Only one hook can be registered for the whole asset
  • If no user update hook is set, the error code 472 (meaning "not supported / not implemented") will be reported to the server.
  • Any error coming from this update request means that the whole update process will be considered as failed.
  • When an update request tries to install a version that is already installed, the application should return success value. Indeed, in some cases the asset instance won't receive and report the hook's result (e.g. because of a poorly timed reboot). As a result, the update request will be sent again, and the hook should report a success immediately.

Parameter

  • hook : the new function to handle software update request. hook signature:
    hook(componentname, version, path, parameters)

    • componentname (string) is the identifier of the component to update, the name is defined in update manifest file, here it is provided without the assetid at the beginning.

    • version (string) is the version of the component to install version can be empty string (but not nil!) to specify de-installation request, non empty string for regular update/install of software component.

    • path (string) can be empty when version is empty too, otherwise path will be a non empty string defining the absolute path of the file/folder to use to update the application.

    • parameters (table), can be nil, when set it contains the content of parameters fields from update package, those parameters provide a way to give application specific update parameters.

    • return value:

      • an integer for synchronous update request result: 200 for success, any other value means error. Values from 480 to 499 are reserved for applicative error codes, so it is highly recommended to use one (or more) of those to signify an error coming from this update hook.
      • "async" string, then the appliacation must send update request result later on using airvantage.asset#asset.sendUpdateResult API.
      • Other non-integer return values will be rejected and be replaced by default value 471, thus setting the update request as failed.

Return values

  1. "ok" on success.

  2. nil followed by an error message otherwise.

asset:start()

Starts a newly created #asset.

Allows the #asset instance to send and receive messages to/from the servers.

An #asset instance which has been started, then experiences an unrecoverable error or an explicit call to asset emits a "closed" event (cf. sched#signal).

Return values

  1. "ok" on success.

  2. nil followed by an error message otherwise.

asset.tree

airvantage.asset data tree

An #asset contains a data tree, in its field tree.

When the server sends data to an asset, the way it reacts is determined by the tree's content:

  • if there's a function in the tree under a path which is the prefix of the data's path, this function is called as a handler;
  • if there's no specific handler, but a handler is found in a __default field in a prefix of the data's path, this generic handler is used. If several generic handlers are found, the one corresponding to the longest prefix is chosen.
  • if no handler is found at all, the value sent by the server is written in the tree, under its path.

For instance, if the server sends myAsset.foo.bar=123:

  • if there's a function in one of myAsset.tree.foo.bar, myAsset.tree.foo or myAsset.tree, this function is called;
  • if there's no such function, but at least one default handler is found in either myAsset.tree.foo.__default or myAsset.tree.__default, the one with the longest path is called;
  • if no handler is found, the value 123 is written in myAsset.tree.foo.bar.

Handlers are functions which receive as parameters:

  • self the asset instance;
  • data the map of keys/values sent by the server; keys are paths relative to the node where the handler is attached;
  • path the path string where the handler is attached; concatenated in front of each key, it allows to retrieve absolute paths.

Handlers must return:

  • the status code 0 to indicate success;
  • a non-zero numeric status code to indicate failure, optionally followed by an error message.

The data tree comes with a pre-installed handler function on the path myAsset.tree.commands.ReadNode. It handles standard requests by the server when it wants to read the content of an arbitrary path in the asset's tree.

Notice that handler functions should be installed in the data tree before the asset is started with asset.start: otherwise, any server message received between the start and the handler attachment will be lost.