Adding Sensors with Sensor API

Easily add sensors to your Milli HDK with Itron's Sensor API

Start building your IoT solution with Itron Milli5. Create an Account


Sensor API provides an easy alternative to classic CoAP server code for adding sensors to Itron Networks using Milli.  This page provides step-by-step instructions to use SAPI functions to add your sensor to a Milli-based solution.


Adding Sensors with SAPI

Itron's Sensor API handles all details of creating a CoAP resource URI for your sensors, and making sensor data available over Itron networks using Milli and CoAP.  To add sensors to your Milli reference application code with SAPI, developers need to:

  • Add initialization code to initialize the sensor
  • Register the sensor with SAPI
  • Provide a function for reading sensor data
  • If the sensor is configurable, provide functions for reading and writing sensor configuration

Example C code for these steps is provided below. Additional information is provided in the Sensor API User's Guide.


Setup Code to Add a Sensor

In the main setup function (located in the source file mshield.cpp), add a call to sapi_register_sensor and sapi_init_sensor for the sensor you are adding:

#include <Arduino.h>
#include "sapi_mshield.h"
#include "sapi_error.h"
#include "sapi.h"
#include "NewSensor.h"

static uint8_t new_sensor_id;

//  Arduino setup function.
void setup()
    sapi_error_t rcode;
    // Initialize Sensor API
    // Register temp sensor
    new_sensor_id = sapi_register_sensor(NEW_SENSOR_TYPE, new_init_sensor, new_read_sensor, newp_read_cfg, new_write_cfg, 1, 180);
    // Initialize temp sensor
    rcode = sapi_init_sensor(new_sensor_id);


Sensor Implementation

Typically, developers will separate sensor implementation into dedicated header and source files, for example NewSensor.h and NewSensor.c.  The sensor implementation includes an initialization function that performs any initialization tasks needed on startup, before the sensor is registered with SAPI and available to provide data.  Initial configuration, setting a default value or performing an initial sensor read, and logging are typical implementation steps a developer would provide in the initialization function.  The prototype for this function is sapi_error_t sensor_init_function_name().

For each sensor, a read function must be supplied.  The prototype for the read function is sapi_error_t sensor_read_function(char *payload, uint8_t *len).  The sensor reading is copied into the payload buffer, and the length of the reading is recorded in len.

If a sensor supports configuration (for example, temperature units in Fahrenheit or Celsius), a configuration read and configuration write function must be implemented, and provided to the sapi_register_sensor function for sensor registration.  The prototypes for sensor read and write configuration functions are:

 * @brief Read sensor configuration. Builds and returns the payload. Callback called on
 *   CoAP Get configuration value
 * @param payload     Pointer to the sensor payload buffer.
 * @param len         Pointer to the CoAP message buffer length.
 * @return SAPI Error Code
sapi_error_t sensor_read_cfg(char *payload, uint8_t *len);

 * @brief Write sensor configuration. Processes payload sent from client. Callback called on
 *   CoAP Put configuration value
 * @param payload     Pointer to the sensor payload buffer.
 * @param len         Pointer to the CoAP message buffer length.
 * @return SAPI Error Code
sapi_error_t sensor_write_cfg(char *payload, uint8_t *len);


Please see the TempSensor code provided in the Milli reference solution for an example of a complete sensor implementation.

Sensor URI and Observations

When you register a sensor, one parameter you must supply is the sensor type. SAPI will use the string you supply for sensor type as part of the CoAP URI that represents that sensor to the network.  For example, suppose you are adding an Oxygen level sensor, and you use "O2" as the sensor type.  The CoAP URI for the temperature sensor would be "snsr/arduino/O2", and a GET operation from a CoAP client to obtain the current Oxygen  level value would be "GET snsr/arduino/O2?sens".

Once you initialize and register a sensor with SAPI, that sensor's URI can also be used to generate observations. If you are using MQTT bubble-up configuration with Milli, that sensor's URI must be supplied as part of the Milli's sysvar 35 configuration. For more information on Milli configuration for observeable resources, see our personalization overview here.

With SAPI you can also send ad-hoc observations from the device to MQTT.  An example of when this might be useful is when the sensor reaches a critical threshold, or when an alarm needs to be sent to subscribers.  SAPI supports unsolicited notifications using the function sapi_error_t sapi_push_notification(uint8_t sensor_id). The push notification will immediately send the specified sensor's current value over the network to any subscribers. Note that sensor_id is the integer value returned after a successful call to sapi_register_sensor!