Monday, May 18, 2015

Make your IoT gateway WiFi-aware using Camel and Kura

This is re-post of my DZone article - Make Your IoT Gateway WiFi-Aware Using Camel and Kura. The original DZone article has been published last week.

The common scenario for the mobile IoT Gateways, for example those mounted on the trucks or the other vehicles, is to cache collected data locally on the device storage and synchronizing the data with the data center only when trusted WiFi access point is available near the gateway. Such trusted WiFi network could be localized near the truck fleet parking.


Using this approach, less urgent data (like GPS coordinates stored for the further offline analysis) can be delivered to the data center without the additional cost related to the GPS transmission fees.



Camel Kura WiFi component from the Camel IoT Labs can be used to retrieve the information about the WiFi access points available within the device range. Under the hood Kura Wifi component uses Kura org.eclipse.kura.net.NetworkService.

Setting up of the Maven project


In order to take advantage of the Camel Kura WiFi component, Maven users should add the following dependency to their POM file:

<dependency>
  <groupId>com.github.camel-labs</groupId>
  <artifactId>camel-kura</artifactId>
  <version>0.0.0</version>
</dependency>

All the other dependencies will be pulled by the Maven transitive resolver.
 

Creating Camel route scanning the WiFi networks


Kura WiFi component supports both the consumer and producer endpoints. In practice it means that you can either periodically scan for the WiFi networks (consumer mode) or explicitly request the single scan (producer mode).

The following Apache Camel route will use the wlan0 interface to scan for the mySsid network. If the mySsid WiFi network will be found, Camel will automatically start the route responsible for the synchronization of the offline data stored on the device local storage with the data center:

  from("kura:wlan0/mySsid").
      to("controlbus:route?routeId=onlineSync&action=start");

  from("file:///var/sensor/temperature").
      routeId("onlineSync").autoStartup(false).
      to("netty4-http://api.mydatacenter.com");
Keep in mind that both network interface and SSID can be replaced with the * wildcards matching respectively all the network interfaces and SSIDs.

For example to read all the SSID available near the device, the following route can be used:

    from("kura:*/*").to(...);


Data returned by the WiFi endpoints


The Kura WiFi consumer returns the list of the org.eclipse.kura.net.wifi.WifiAccessPoint classes returned as a result of the WiFi scan:
    ConsumerTemplate consumerTemplate = camelContext.createConsumerTemplate();
    WifiAccessPoint[] accessPoints = consumerTemplate.receiveBody("kura:wlan0/*", WifiAccessPoint[].class);
You can also request the WiFi scanning using the producer endpoint:
        from("direct:WifiScan").to("kura-wifi:*/*").to("mock:accessPoints");
 
Or using the producer template directly:

    ProducerTemplate template = camelContext.createProducerTemplate();
    WifiAccessPoint[] accessPoints = template.requestBody("kura-wifi:*/*", null, WifiAccessPoint[].class);


Deployment options


Camel Kura WiFi component can be deployed either as the OSGi bundle, directly into the Kura container:

  public class WifiKuraRouter extends KuraRouter {

    @Override
    public void configure() throws Exception {
      from("kura-wifi:*/*").to("log:availableWifiNetworks");
    }

  }

...where KuraRouter is the base OSGi bundle activator for Camel routes deployable into Kura.

The other option of deployment is to use Spring Boot based fat jar:

  @SpringBootApplication
  public class WifiKuraRouter extends FatJar {

    @Override
    public void configure() throws Exception {
      from("kura-wifi:*/*").to("log:availableWifiNetworks");
    }

  }

In the first place Kura Wifi component tries to locate the org.eclipse.kura.net.NetworkService instance in the Camel registry. If exactly one instance of the NetworkService is found (this is usually the case when if you deploy the route into the Kura container), that instance will be used by the Kura component. Otherwise new instance of the org.eclipse.kura.linux.net.NetworkServiceImpl will be created and cached by the KuraAccessPointsProvider.


Summary


Smart WiFi connectivity is fundamental for every mobile IoT gateway solution. Camel Kura WiFi integration makes WiFi scanning process as easy as adding a few lines of the DSL. Your gateway application should try to cache the data collected from the sensors and avoid using the expensive mobile connectivity whenever possible. The efficient IoT gateway should synchronize the stored offline data when the trusted WiFi network is available.