Sensor API

This page presents the base API that one needs to implement to add support for new sensors or actuators.

This API can only be used to implement drivers for single sensors (this limitation is due to the fact that the base API only allows the driver to define a single Feature of Interest (FOI) and a single sensor description). This means that a driver implementing only the base API would have to be instantiated N times to connect to a network of N sensors. Fortunately, SensorHub also defines an extension to the base sensor API allowing one to write drivers that can wrap sensor networks of any size within a single module. Please see the Sensor Network API page for more details.

When implementing the base sensor API, each new sensor (or actuator) driver is composed of at least 4 classes:

Details about these different classes are given in the next sections.

Note: Several sensor drivers can be packaged in a single Maven module, although we encourage this only if the drivers are very closely related and/or have tight inter-dependencies.

ISensorModule

The ISensorModule interface is the top-level one to be implemented by sensor drivers. It provides methods for:

  • Getting the SensorML description of an installed sensor or actuator
  • Getting the feature of interest (FOI) currently observed by the sensor
  • Checking for the presence of the device
  • Subscribing for high level sensor events (activation, connection, etc.)
  • Giving access to the sensor measurement outputs and control inputs

The main functions of the sensor module are shown on the figure below:

fig1

Each data interface is an output that gives access to a stream of sensor measurements and is an implementation of ISensorDataInterface. Data interfaces are asynchornous in the sense that each of them can produce data at a different rate.

Each control interface is an input that can receive commands and is an implementation of ISensorControlInterface. Each control input can receive different types of command messages.

A sensor module implementation must also provide the description of the sensor as a SensorML process (any class derived from AbstractProcess is acceptable). Usually, this sensor description is a mix between information auto-generated by the driver and information provided as a SensorML file by the user. Versioning and updating the sensor description can be optionnally supported by the driver.

In order to help you implement the API, we provide the AbstractSensorModule class that is a simple partial implementation of ISensorModule and can be used as the base for most sensor modules. It provides default implementations of most methods in the API.

ISensorDataInterface

Data produced by each output must be made available by an implementation of ISensorDataInterface that provides methods for:

  • Describing the data structure of each measurement record
  • Reading data produced by a sensor (poll mode)
  • Subscribing for data produced by a sensor (push mode)
  • Discovery methods allowing to advertise if push and storage are supported

The measurement record description must be provided as a tree of SWE Common data components (DataRecord, DataArray, Quantity, Time, Count, etc.). This structure will automatically be used to populate the output section of the SensorML description.

A recommended encoding must also be defined which is usually text for simple measurements and some binary flavor for imagery, video and other multi-dimensionnal datasets.

These components and encodings are provided by the lib-swe-common module.

All data streamed through the same data interface must be synchronous and time-tagged together.

The AbstractSensorOutput class is provided to reduce redundant code and help you get started. It is a basic partial implementation of ISensorDataInterface that can be used as the base for most sensor modules.

ISensorControlInterface

Commands can be sent to the sensor via implementations of ISensorControlInterface that provides methods for:

  • Sending commands to the sensor/actuator (synchronous or asynchronous)
  • Scheduling commands to be sent asynchronously and/or at specific times
  • Subscribing to events related to a command that is executed asynchronously

The AbstractSensorControl class is provided to reduce redundant code and help you get started. It is a basic partial implementation of ISensorControlInterface that can be used as the base for most sensor modules.

SensorConfig

A configuration class derived from SensorConfig must be provided with the new driver. This class is used as a struct that contain public fields carrying the configuration of the sensor module.

All public fields in this class are used to automatically generate the administration user interface of this particular driver. Nesting configuration classes is supported.

You can use the DisplayInfo annotation to give hints to the UI renderer, by providing:

  • A more readable label (if non is provided, the label is automatically derived from the field name)
  • A description that will show up in a popup

AbstractSensorModule

The AbstractSensorModule class can serve as a base to develop most sensor drivers. It provides default implementation for the following aspects:

  • Keeping maps of outputs and command inputs. Derived classes should thus call the addOutput() and addControlInput() methods
  • Generation of SensorML description (more details are given below)

However, there is no default support for:

  • Updating the sensor description from outside the driver (except by changing the base SensorML file)
  • Maintaining a history of sensor descriptions (this is because, by default, this feature is better handled by the persistence layer in SensorHub).

Consequently, the AbstractSensorModule class returns false in the two methods reporting support of these functionalities.

Default workflow for generating the SensorML description

The default workflow shown on the figure below illustrates the way the current sensor decription is generated when you derive a concrete driver implementation from AbstractSensorModule:

fig2

  1. Output, control inputs and configuration parameter descriptions are actually defined by concrete driver implementation but appending to SensorML is done in AbstractSensorModule

  2. Autogenerated content is usually info obtained directly from sensor hardware (e.g. serial number, etc.) and/or internal driver state (e.g. depending on commands received)

IModuleDescriptor

Like any SensorHub module, a sensor driver must implement a class derived from this interface to become discoverable.